How to use a trigger to set the width of user control according to the numer of items in ItemsControl?

ComptonAlvaro 166 Reputation points
2021-03-13T10:16:47.343+00:00

I have a user control that I create to show months of a calendar. I would like to set the size of the user control of the month according to the number of items that I have, the number if items it is the numbers of calenders to show.

This is the xaml if my main user control:

<ItemsControl Name="icCalendarios" ItemsSource="{Binding Calendarios}" Margin="0,0,30,0" Padding="0, 0, 0, 0" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="Auto" Grid.Row="1">

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ControlesGts:UserControlMesConEventos VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,0,0" Padding="0,0,0,0">
                    <ControlesGts:UserControlMesConEventos.Style>
                        <Style TargetType="ControlesGts:UserControlMesConEventos">
                            <Setter Property="WidthReescalado" Value="205"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="1">
                                    <Setter Property="WidthReescalado" Value="700"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="2">
                                    <Setter Property="WidthReescalado" Value="450"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="3">
                                    <Setter Property="WidthReescalado" Value="450"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="4">
                                    <Setter Property="WidthReescalado" Value="450"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="5">
                                    <Setter Property="WidthReescalado" Value="275"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="6">
                                    <Setter Property="WidthReescalado" Value="275"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="7">
                                    <Setter Property="WidthReescalado" Value="250"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="8">
                                    <Setter Property="Width" Value="250"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="9">
                                    <Setter Property="WidthReescalado" Value="250"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="10">
                                    <Setter Property="WidthReescalado" Value="205"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="11">
                                    <Setter Property="WidthReescalado" Value="205"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="12">
                                    <Setter Property="WidthReescalado" Value="205"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ControlesGts:UserControlMesConEventos.Style>
                </ControlesGts:UserControlMesConEventos>
    </ItemsControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>

This is my view model of the main user control:

private ObservableCollection<UserControlMesConEventos> _calendarios = new ObservableCollection<UserControlMesConEventos>();
public ObservableCollection<UserControlMesConEventos> Calendarios
{
    get { return _calendarios; }
    set
    {
        _calendarios = value;
        base.RaisePropertyChangedEvent(nameof(Calendarios));
    }
}



private void CrearCalendarios()
{
    UserControlMesConEventos miCalendarioMesConEventos = new UserControlMesConEventos();
    //miCalendarioMesConEventos.WidthReescalado = anchoCalendario;
    Calendarios.Add(miCalendarioMesConEventos);
}

This is thexaml of the user control for the month:

<Grid>
    <Viewbox Name="vbReescalado" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" Stretch="Uniform"
             Width="{Binding ElementName=MesConEventos, Path=WidthReescalado}">
        <DockPanel>
            <TextBlock Text="{Binding Date}" />

            <Grid Height="30" DockPanel.Dock="Top">
                <TextBox Foreground="Black" Name="txtEncabezado" FontSize="12"
                                         BorderBrush="Transparent" BorderThickness="0" Background="Transparent"
                                         VerticalAlignment="Center" TextAlignment="Center" HorizontalAlignment="Stretch"
                                         Padding="25,0,0,0"
                                         Text="{Binding Encabezado}"/>
            </Grid>


            <ItemsControl ItemsSource="{Binding NombresDias}" DockPanel.Dock="Top" Grid.Column="1">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock TextAlignment="Center" Text="{Binding}" FontSize="8"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="1" Columns="8" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>

            <ItemsControl ItemsSource="{Binding Dias}" Grid.Column="1" Margin="0,0,0,0">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border BorderThickness="0.25" Padding="0,0,0,0" Margin="0,0,0,0"
                                                BorderBrush="{Binding Converter={StaticResource ColorRecuadroDiaConverter}}"
                                                Width="25" Height="25">

                            <Border Name="InnerBorder" Background="{Binding ColorDia}" BorderBrush="{Binding Path=ColorRecuadroExterno}" BorderThickness="{Binding Path=GrosorRecuadroExterno}" Padding="0,0,0,0" Margin="0,0,0,0">
                                <DockPanel>
                                    <!--Número de día.-->
                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" FlowDirection="RightToLeft">
                                        <TextBox TextAlignment="Center" BorderBrush="Transparent" Background="Transparent" Text="{Binding Path=., Converter={StaticResource DateConverter}}" FontSize="5" Margin="0,0,0,0" Padding="0,0,0,0">
                                            <TextBox.Style>

                                                <Style TargetType="{x:Type TextBox}">
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding IsTargetMonth}" Value="false">
                                                            <Setter Property="TextBlock.Foreground" Value="Gray"></Setter>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </TextBox.Style>
                                        </TextBox>
                                    </StackPanel>

                                    <TextBox IsEnabled="{Binding IsEnabled}" FontSize="2.5" Height="18" AcceptsReturn="True" TextWrapping="Wrap" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Disabled"
                                                             Background="{x:Null}"
                                                             Foreground="{Binding Path=ColorTexto}"
                                                             Text="{Binding Path=Notes}"/>

                                </DockPanel>
                            </Border>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="6" Columns="8" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DockPanel>
    </Viewbox>
</Grid>

And this is the code behind:

public static readonly DependencyProperty WidthReescaladoProperty =
     DependencyProperty.Register("WidthReescalado", typeof(double)
         , typeof(UserControlMesConEventos), new FrameworkPropertyMetadata(0.0));
public double WidthReescalado
{
    get
    {
        return (double)GetValue(WidthReescaladoProperty);
    }
    set
    {
        SetValue(WidthReescaladoProperty, value);
    }
}

I have a user control that I create to show months of a calendar. I would like to set the size of the user control of the month according to the number of items that I have, the number if items it is the numbers of calenders to show.

This is the xaml of my main user control:

<ItemsControl Name="icCalendarios" ItemsSource="{Binding Calendarios}" Margin="0,0,30,0" Padding="0, 0, 0, 0" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="Auto" Grid.Row="1">

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <ControlesGts:UserControlMesConEventos VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,0,0" Padding="0,0,0,0">
                        <ControlesGts:UserControlMesConEventos.Style>
                            <Style TargetType="ControlesGts:UserControlMesConEventos">
                                <Setter Property="WidthReescalado" Value="205"/>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="1">
                                        <Setter Property="WidthReescalado" Value="700"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="2">
                                        <Setter Property="WidthReescalado" Value="450"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="3">
                                        <Setter Property="WidthReescalado" Value="450"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="4">
                                        <Setter Property="WidthReescalado" Value="450"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="5">
                                        <Setter Property="WidthReescalado" Value="275"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="6">
                                        <Setter Property="WidthReescalado" Value="275"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="7">
                                        <Setter Property="WidthReescalado" Value="250"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="8">
                                        <Setter Property="Width" Value="250"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="9">
                                        <Setter Property="WidthReescalado" Value="250"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="10">
                                        <Setter Property="WidthReescalado" Value="205"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="11">
                                        <Setter Property="WidthReescalado" Value="205"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=icCalendarios, Path=ItemsSource.Count}" Value="12">
                                        <Setter Property="WidthReescalado" Value="205"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ControlesGts:UserControlMesConEventos.Style>
                    </ControlesGts:UserControlMesConEventos>
        </ItemsControl>
                </DataTemplate>
            </ItemsControl.ItemTemplate>

This is my view model of the main user control:

private ObservableCollection<UserControlMesConEventos> _calendarios = new ObservableCollection<UserControlMesConEventos>();
public ObservableCollection<UserControlMesConEventos> Calendarios
{
    get { return _calendarios; }
    set
    {
        _calendarios = value;
        base.RaisePropertyChangedEvent(nameof(Calendarios));
    }
}



private void CrearCalendarios()
{
    UserControlMesConEventos miCalendarioMesConEventos = new UserControlMesConEventos();
    //miCalendarioMesConEventos.WidthReescalado = anchoCalendario;
    Calendarios.Add(miCalendarioMesConEventos);
}

This is the xaml of the user control for the month:

<Grid>
    <Viewbox Name="vbReescalado" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" Stretch="Uniform"
             Width="{Binding ElementName=MesConEventos, Path=WidthReescalado}">
        <DockPanel>
            <TextBlock Text="{Binding Date}" />

            <Grid Height="30" DockPanel.Dock="Top">
                <TextBox Foreground="Black" Name="txtEncabezado" FontSize="12"
                                         BorderBrush="Transparent" BorderThickness="0" Background="Transparent"
                                         VerticalAlignment="Center" TextAlignment="Center" HorizontalAlignment="Stretch"
                                         Padding="25,0,0,0"
                                         Text="{Binding Encabezado}"/>
            </Grid>


            <ItemsControl ItemsSource="{Binding NombresDias}" DockPanel.Dock="Top" Grid.Column="1">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock TextAlignment="Center" Text="{Binding}" FontSize="8"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="1" Columns="8" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>

            <ItemsControl ItemsSource="{Binding Dias}" Grid.Column="1" Margin="0,0,0,0">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border BorderThickness="0.25" Padding="0,0,0,0" Margin="0,0,0,0"
                                                BorderBrush="{Binding Converter={StaticResource ColorRecuadroDiaConverter}}"
                                                Width="25" Height="25">

                            <Border Name="InnerBorder" Background="{Binding ColorDia}" BorderBrush="{Binding Path=ColorRecuadroExterno}" BorderThickness="{Binding Path=GrosorRecuadroExterno}" Padding="0,0,0,0" Margin="0,0,0,0">
                                <DockPanel>
                                    <!--Número de día.-->
                                    <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" FlowDirection="RightToLeft">
                                        <TextBox TextAlignment="Center" BorderBrush="Transparent" Background="Transparent" Text="{Binding Path=., Converter={StaticResource DateConverter}}" FontSize="5" Margin="0,0,0,0" Padding="0,0,0,0">
                                            <TextBox.Style>

                                                <Style TargetType="{x:Type TextBox}">
                                                    <Style.Triggers>
                                                        <DataTrigger Binding="{Binding IsTargetMonth}" Value="false">
                                                            <Setter Property="TextBlock.Foreground" Value="Gray"></Setter>
                                                        </DataTrigger>
                                                    </Style.Triggers>
                                                </Style>
                                            </TextBox.Style>
                                        </TextBox>
                                    </StackPanel>

                                    <TextBox IsEnabled="{Binding IsEnabled}" FontSize="2.5" Height="18" AcceptsReturn="True" TextWrapping="Wrap" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Disabled"
                                                             Background="{x:Null}"
                                                             Foreground="{Binding Path=ColorTexto}"
                                                             Text="{Binding Path=Notes}"/>

                                </DockPanel>
                            </Border>
                        </Border>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Rows="6" Columns="8" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </DockPanel>
    </Viewbox>
</Grid>

And this is the code behind:

public static readonly DependencyProperty WidthReescaladoProperty =
     DependencyProperty.Register("WidthReescalado", typeof(double)
         , typeof(UserControlMesConEventos), new FrameworkPropertyMetadata(0.0));
public double WidthReescalado
{
    get
    {
        return (double)GetValue(WidthReescaladoProperty);
    }
    set
    {
        SetValue(WidthReescaladoProperty, value);
    }
}

I have realize if I set the property WidthReescalado in the view model of the main user control (in the code I have commented this line) it works, but if I try to set the width in the xaml of the main user control I can't. And I set as default value 205, so the problem is not only becuase of the triggers, but it seems that the value is not set correctly.

I have try also set the property of the user control directly, but it doesn't work too:

<ControlesGts:UserControlMesConEventos WidthReescalado="205" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,0,0" Padding="0,0,0,0">

How could I set the width in the xaml? Because i guess this is better to set in the view instead of the view model.

Thanks.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,681 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
767 questions
{count} votes