-2

I have the same design and function for every column in my UI but it is very annoying to update something, since I have to do it for every column. Can someone help me to simplify it somehow? I already looked up a lot in the internet but I found no possibility, I want to do something like: <Datagridentry (push monday)> <Datagridentry (push tuesday)> and so on...

and simply one layout which gets filled with the data.

<DataGridTextColumn Binding="{Binding Path=FirstWeek.Monday.Content}" x:Name="Column1" Width="50">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock 
                                Background="{Binding Path=DataContext.ColorsArray[0], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                HorizontalAlignment="Center"
                                Text="Mo" 
                                Grid.Row="0"/>
                            <TextBlock
                                HorizontalAlignment="Center"
                                Text="{Binding Path=DataContext.MonthDaysDate[0], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                Grid.Row="1">
                            </TextBlock>
                        </Grid>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="TextBlock">
                        <Setter Property="Margin" Value="10,5,10,5"/>
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="VerticalAlignment" Value="Center" />
                    </Style>
                </DataGridTextColumn.ElementStyle>
                <DataGridTextColumn.CellStyle >
                    <Style TargetType="DataGridCell">
                        <EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <ToolTip  Visibility="{Binding FirstWeek.Monday,Converter={StaticResource ContentVisibilityConverter}}">
                                    <StackPanel>
                                        <TextBlock Text="{Binding FirstWeek.Monday.Dienstbezeichnung}"/>
                                        <TextBlock Text="{Binding FirstWeek.Monday.Comment}" Visibility="{Binding FirstWeek.Monday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
                                    </StackPanel>
                                </ToolTip>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding FirstWeek.Monday, Converter={StaticResource CheckCellItem} }" Value="True"/>
                                    <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{Binding FirstWeek.Monday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn Binding="{Binding Path=FirstWeek.Tuesday.Content}" x:Name="Column2"  Width="50">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"   />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock 
                                Background="{Binding Path=DataContext.ColorsArray[1], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                HorizontalAlignment="Center"
                                Text="Di" 
                                Grid.Row="0" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                Text="{Binding Path=DataContext.MonthDaysDate[1], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                Grid.Row="1"/>
                        </Grid>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
              
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="TextBlock">
                        <Setter Property="Margin" Value="10,5,10,5"/>
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="VerticalAlignment" Value="Center" />
                    </Style>
                </DataGridTextColumn.ElementStyle>
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <ToolTip Visibility="{Binding FirstWeek.Tuesday,Converter={StaticResource ContentVisibilityConverter}}">
                                    <StackPanel>
                                        <TextBlock Text="{Binding FirstWeek.Tuesday.Dienstbezeichnung}"/>
                                        <TextBlock Text="{Binding FirstWeek.Tuesday.Comment}" Visibility="{Binding FirstWeek.Tuesday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>

                                    </StackPanel>
                                </ToolTip>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding FirstWeek.Tuesday, Converter={StaticResource CheckCellItem} }" Value="True"/>
                                    <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{Binding FirstWeek.Tuesday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>

            <DataGridTextColumn Binding="{Binding Path=FirstWeek.Wednesday.Content}" Header="Mi" x:Name="Column3" Width="50">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"   />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock 
                                Background="{Binding Path=DataContext.ColorsArray[2], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                HorizontalAlignment="Center"
                                Text="Mi" 
                                Grid.Row="0" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                Text="{Binding Path=DataContext.MonthDaysDate[2], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                Grid.Row="1"/>
                        </Grid>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="TextBlock">
                        <Setter Property="Margin" Value="10,5,10,5"/>
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="VerticalAlignment" Value="Center" />
                    </Style>
                </DataGridTextColumn.ElementStyle>
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <ToolTip Visibility="{Binding FirstWeek.Wednesday,Converter={StaticResource ContentVisibilityConverter}}">
                                    <StackPanel>
                                        <TextBlock Text="{Binding FirstWeek.Wednesday.Dienstbezeichnung}"/>
                                        <TextBlock Text="{Binding FirstWeek.Wednesday.Comment}" Visibility="{Binding FirstWeek.Wednesday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>

                                    </StackPanel>
                                </ToolTip>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding FirstWeek.Wednesday, Converter={StaticResource CheckCellItem} }" Value="True"/>
                                    <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{Binding FirstWeek.Wednesday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>

            <DataGridTextColumn Binding="{Binding Path=FirstWeek.Thursday.Content}" Header="Do" x:Name="Column4" Width="50">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"   />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock 
                                Background="{Binding Path=DataContext.ColorsArray[3], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                HorizontalAlignment="Center"
                                Text="Do" 
                                Grid.Row="0" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                Text="{Binding Path=DataContext.MonthDaysDate[3], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                Grid.Row="1"/>
                        </Grid>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="TextBlock">
                        <Setter Property="Margin" Value="10,5,10,5"/>
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="VerticalAlignment" Value="Center" />
                    </Style>
                </DataGridTextColumn.ElementStyle>
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <ToolTip  Visibility="{Binding FirstWeek.Thursday,Converter={StaticResource ContentVisibilityConverter}}">
                                    <StackPanel>
                                        <TextBlock Text="{Binding FirstWeek.Thursday.Dienstbezeichnung}"/>
                                        <TextBlock Text="{Binding FirstWeek.Thursday.Comment}" Visibility="{Binding FirstWeek.Thursday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>

                                    </StackPanel>
                                </ToolTip>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding FirstWeek.Thursday, Converter={StaticResource CheckCellItem} }" Value="True"/>
                                    <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{Binding FirstWeek.Thursday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
                            </MultiDataTrigger>
                        </Style.Triggers>

                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>

            <DataGridTextColumn Binding="{Binding Path=FirstWeek.Friday.Content}" Header="Fr" x:Name="Column5" Width="50">
                <DataGridTextColumn.HeaderTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"   />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock 
                                Background="{Binding Path=DataContext.ColorsArray[4], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                HorizontalAlignment="Center"
                                Text="Fr" 
                                Grid.Row="0" />
                            <TextBlock
                                HorizontalAlignment="Center"
                                Text="{Binding Path=DataContext.MonthDaysDate[4], RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                                Grid.Row="1"/>
                        </Grid>
                    </DataTemplate>
                </DataGridTextColumn.HeaderTemplate>
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="TextBlock">
                        <Setter Property="Margin" Value="10,5,10,5"/>
                        <Setter Property="HorizontalAlignment" Value="Center" />
                        <Setter Property="VerticalAlignment" Value="Center" />
                    </Style>
                </DataGridTextColumn.ElementStyle>
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <EventSetter Event="MouseUp" Handler="DataGridCell_PreviewMouseUp"/>
                        <Setter Property="ToolTip">
                            <Setter.Value>
                                <ToolTip  Visibility="{Binding FirstWeek.Friday,Converter={StaticResource ContentVisibilityConverter}}">
                                    <StackPanel>
                                        <TextBlock Text="{Binding FirstWeek.Friday.Dienstbezeichnung}"/>
                                        <TextBlock Text="{Binding FirstWeek.Friday.Comment}" Visibility="{Binding FirstWeek.Friday.Comment,Converter={StaticResource ContentVisibilityConverter}}"/>
                                    </StackPanel>
                                </ToolTip>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <MultiDataTrigger>
                                <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding FirstWeek.Friday, Converter={StaticResource CheckCellItem} }" Value="True"/>
                                    <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="False"/>
                                </MultiDataTrigger.Conditions>
                                <Setter Property="Background" Value="{Binding FirstWeek.Friday.ContentColor, Converter={StaticResource ColorStringToColorConverter}}"></Setter>
                            </MultiDataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
Yessir
  • 183
  • 3
  • 13
  • I've not double checked all the stuff you're working with but I would think another abstraction layer. Translate your data so it's easier to work with. Flatten out your data into a class with a property for each of those things you're interested in. Call that a FlatVM. Define a row viewmodel with multiple FlatVM properties. What is that... monday, tuesday etc? If the datagrid is read only you can use an array for days of week. You can then have one template and style re-used for each column. Assuming these are all repeated. – Andy Oct 20 '20 at 13:59
  • My grid is not read only, I am searching for a way to simplify my grid. – Yessir Oct 20 '20 at 14:15
  • Then use separate properties Monday, Tuesday etc rather than an array. The entire approach I outlined is not dependent on the datagrid being readonly. – Andy Oct 20 '20 at 14:40
  • this is only a part of the datagrid, there is FirstWeek, SecondWeek, Thirdweek and so on – Yessir Oct 21 '20 at 05:18

1 Answers1

1

The ElementStyle can be defined as a resource and be referenced using the StaticResource markup extension.

It's worse with the data templates since you cannot dynamically replace only a binding path in a template and keep the rest in XAML.

You may consider to create the templates programmtically using the XamlReader.Parse method. This will let you use a method like string.Replace to replace the binding path for each column. You will still have to create a template per column but it will let you define the XAML markup for the template once.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Would it be possible to generate columns from code behind? Since I always have x amount of columns – Yessir Oct 21 '20 at 09:25
  • Sure but how is this related to your original issue? – mm8 Oct 21 '20 at 12:12
  • Then I can set the properties and all the UI stuff from the code behind, – Yessir Oct 21 '20 at 12:25
  • Creating the templates programmatically is what I suggested in my answer, isn't it? You still need to define the templates somehere, even if you create the *columns* programmatically. – mm8 Oct 21 '20 at 12:26
  • Yes, can you give an example how I could build my application using this XamlReader? – Yessir Oct 21 '20 at 12:32
  • @H.Füreder: https://stackoverflow.com/a/44757321/7252182 – mm8 Oct 21 '20 at 12:34
  • And you mentioned it is necessary to create a template per column? I want to somehow prevent this. Since this would still be a lot of work if I have 40 columns or do I misunderstand something? – Yessir Oct 21 '20 at 12:34
  • Yes, you need a template per column but you could define the XAML once and then call `string.Replace` and `XamlReader.Parse` in a loop. – mm8 Oct 21 '20 at 12:35
  • Ah okay I understand, can I do the same with the DataGridTextColumn? – Yessir Oct 21 '20 at 12:37
  • You mean for the `CellTemplate`? Yes. – mm8 Oct 21 '20 at 12:38
  • I mean DataGridTextColum, as you can see there is a lot of repetetive stuff in my xaml, Datagrid.HeaderTemplate DataGridTextColumn.CellStyle. – Yessir Oct 21 '20 at 12:41
  • Yes, you should use `XamlReader.Parse` to create these as I told you... – mm8 Oct 21 '20 at 12:41
  • I hardly ever touched the code behind, because I only use the MVVM pattern, but with this one I will not get any further here. I will look up more details about the XamlReader and come back later here. – Yessir Oct 21 '20 at 12:44
  • The MVVM pattern is not about eliminating code-behind. It's about separation of concerns. You can define an entire view using C# without violating MVVM. – mm8 Oct 21 '20 at 12:45
  • I used the code behind to generate the whole Datagrid, I didn't use the XAML parser, I create the elements by myself. What is the smoothest way now to combine that with the MVVM Pattern, because I have now a two-dimensional array in the code behind which manages the Datagrid, but I have the other stuff in a MainViewModel doing all the other stuff – Yessir Oct 22 '20 at 06:34
  • If you just moved the stuff you previously had in the XAML markup to the code-behind, there is no difference as far as MVVM is concerned. The XAML and the code-behind are belong to the same class. – mm8 Oct 22 '20 at 13:24
  • You may have a look at my new question please – Yessir Nov 02 '20 at 06:35
  • @H.Füreder: What new question? – mm8 Nov 02 '20 at 14:02
  • Have a look now – Yessir Nov 02 '20 at 14:13
  • https://stackoverflow.com/questions/64606210/wpf-datagrid-is-refreshing-very-slowly – Yessir Nov 02 '20 at 14:13
  • @H.Füreder: What about this question? Is it solved? – mm8 Nov 02 '20 at 15:17
  • My Datagrid is very slow loading and it is not solved – Yessir Nov 02 '20 at 15:19
  • How is this related to this question? – mm8 Nov 02 '20 at 15:20
  • Since I have dynamic columns, my Datagrid is very slow, I thought you might have a clue about the problem. – Yessir Nov 02 '20 at 15:23
  • @H.Füreder: I still don't understand why you haven't accepted this answer. – mm8 Nov 02 '20 at 15:24