WPF User Control - A Concrete Way to Get the Right Width Ratio

I am creating a control to represent an employee shift. The shift can have different lengths and without any interruptions.

Mockup prototype GUI of a 9 hour work shift with an 1 hour break GUI prototype layout for a 9-hour work shift with a 1-hour break

The following questions relate to the blue bar in the prototype: Since the control should change a lot, a fixed-size approach is not an option. My first thought was to use a grid with columns that have the same width ratio as time intervals. Therefore, if you look at the prototype above, there will be 3 columns with a width: 240 *, 60 *, 240 *. These numbers are equal to the total number of minutes of each period of time.

If I add a dependency property that holds, let's call them TimeSpanItems (TSI). Each TSI has a TimeSpan property. Can this be related to the grid and its column definitions? The number of columns must change as TSI is added, and each column must change the width factor according to the number of minutes.

Am I thinking about it wrong? Is this doable? Or is it the control that I need, which resizes its elements when the control is resized?

At the moment, I have different questions that I have not yet found an answer to ... and probably a lot of questions that I still do not know what they are. Any help would be appreciated.

+3
source share
2 answers

: ? , , . , . , , "" .

... , uxMainContentGrid - , .

<Style TargetType="{x:Type wpflib:RatioPresenterControl}">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type wpflib:RatioPresenterControl}">
            <Border Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Height="{TemplateBinding Height}"
                    Width="{TemplateBinding Width}">

                <Grid x:Name="uxMainContentGrid">
                    <Grid.ColumnDefinitions>
                        <!-- Columns and ratio is set in code behind -->
                    </Grid.ColumnDefinitions>
                </Grid>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>

                                                                                                                                                                                      

, , .

Public Class RatioItem
    Public Property Value As Double
    Public Property Brush As Brush
End Class

RatioItems RatioItems.

 Public Shared ReadOnly RatioItemsProperty As DependencyProperty = _
        DependencyProperty.Register("RatioItems", GetType(IEnumerable(Of RatioItem)),
              GetType(RatioPresenterControl),
              New FrameworkPropertyMetadata(New List(Of RatioItem), AddressOf OnRatioItemsPropertyChanged))

, , . , . , .

Public Shared Sub OnRatioItemsPropertyChanged(sender As Object, e As DependencyPropertyChangedEventArgs)
    If (_MainContentGrid IsNot Nothing) Then
        Dim ratioItems As IEnumerable(Of RatioItem) = TryCast(e.NewValue, IEnumerable(Of RatioItem))

        ReconstructGridColumns(ratioItems, _MainContentGrid)
    End If
End Sub

. , , RatioItems . , , .

Public Overrides Sub OnApplyTemplate()
    MyBase.OnApplyTemplate()

    _MainContentGrid = TryCast(Me.Template.FindName("uxMainContentGrid", Me), Grid)

    ReconstructGridColumns(Me.RatioItems, _MainContentGrid)
End Sub

""...

Private Shared Sub ReconstructGridColumns(ByVal ratioItems As IEnumerable(Of RatioItem), ByVal mainContentGrid As Grid)
    Dim newContent As Rectangle
    Dim columnCount As Integer = 0

    mainContentGrid.ColumnDefinitions.Clear()

    For Each item In ratioItems
        mainContentGrid.ColumnDefinitions.Add(New ColumnDefinition() With {.Width = New GridLength(item.Value, GridUnitType.Star)})
        newContent = New Rectangle() With {.Name = "item" & columnCount, .Fill = item.Brush}
        mainContentGrid.Children.Add(newContent)
        Grid.SetColumn(newContent, columnCount)
        columnCount += 1
    Next
End Sub

. . , "" ...:)

0

-, , :

Task timeline

, "", .

- ItemsControl, :

<ItemsControl ItemsSource="{Binding Path=Tarefas}" Grid.Column="4">
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Border Grid.Row="0" Background="SlateGray" Margin="5 5 5 5">
                    <TextBlock Grid.ColumnSpan="100" Text="Cronograma" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" />
                </Border>
                <ItemsPresenter Grid.Row="1" />
            </Grid>
        </ControlTemplate>
    </ItemsControl.Template>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid Style="{StaticResource CronogramaGrid}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="{Binding Converter={StaticResource InicioPerc}}" />
                    <ColumnDefinition Width="{Binding Converter={StaticResource MeioPerc}}" />
                    <ColumnDefinition Width="{Binding Converter={StaticResource FimPerc}}" />
                </Grid.ColumnDefinitions>
                <Border Background="SlateGray" Grid.Column="1">
                    <Border Background="White" Margin="2 2 2 2">
                        <Grid Margin="2 2 2 2">
                            <Border Background="SlateGray" />
                            <ItemsControl ItemsSource="{Binding Path=PercentagensParticipacao}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Grid Height="{Binding Path=GridHeight}">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding Path=Actual, Converter={StaticResource GridLengthStarConverter}}" />
                                                <ColumnDefinition Width="{Binding Path=Restante, Converter={StaticResource GridLengthStarConverter}}" />
                                            </Grid.ColumnDefinitions>
                                            <Border Grid.Column="0" Background="{Binding Path=Index, Converter={StaticResource IndexColorConverter}}" />
                                        </Grid>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </Grid>
                    </Border>
                </Border>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

. , , , , , , Getter .

:

public class DataInicioPercentagemConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var tarefa = (Tarefa)value;
        var candidatura = Indra.Injection.ServiceLocator.MefContainer.GetExportedValue<IDataManager>().Candidatura;

        double totalDias = candidatura.DataFim.Subtract(candidatura.DataInicio).Days;
        double diasTarefaInicio = tarefa.Inicio.Subtract(candidatura.DataInicio).Days;

        return new GridLength((diasTarefaInicio / totalDias * 100), GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

public class DataMeioPercentagemConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var tarefa = (Tarefa)value;
        var candidatura = Indra.Injection.ServiceLocator.MefContainer.GetExportedValue<IDataManager>().Candidatura;

        double totalDias = candidatura.DataFim.Subtract(candidatura.DataInicio).Days;
        double diasTarefa = tarefa.Fim.Subtract(tarefa.Inicio).Days;

        return new GridLength((diasTarefa / totalDias * 100), GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

public class DataFimPercentagemConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var tarefa = (Tarefa)value;
        var candidatura = Indra.Injection.ServiceLocator.MefContainer.GetExportedValue<IDataManager>().Candidatura;

        double totalDias = candidatura.DataFim.Subtract(candidatura.DataInicio).Days;
        double diasTarefaFim = candidatura.DataFim.Subtract(tarefa.Fim).Days;

        return new GridLength((diasTarefaFim / totalDias * 100), GridUnitType.Star);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}
0

All Articles