1 year ago

#387078

test-img

Patb

How to simplify verbose WPF DataGrid Xaml?

I have a WPF DataGrid with many columns (below I showed only 3 columns for simplicity). To mark up a single column it takes almost 20 lines of code and it repeats for every column. The only difference between the columns is the header text and the binding.

MainView.xaml:

<Window x:Class="UserInterface.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:Converters="clr-namespace:UserInterface.Converters"
        xmlns:UiUtilities="clr-namespace:.UserInterface.UIUtilities"
        mc:Ignorable="d"
        Icon="Application.ico"
        Title="{Binding WindowTitle}"
        SizeToContent="WidthAndHeight"
        ResizeMode="NoResize"
        DataContext="{Binding MainViewModel}">

    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
        <Converters:VisibleIfOfTypeXConverter x:Key="VisibleIfOfTypeX" />
    </Window.Resources>

    <DataGrid ItemsSource="{Binding DataModel}" HeadersVisibility="Column" AutoGenerateColumns="False">

        <DataGrid.Columns>

            <DataGridTemplateColumn Header="Header1">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate DataType="UserInterface:SomeType">
                        <Grid>
                            <TextBox Visibility="{Binding Converter={StaticResource VisibleIfOfTypeX}}">
                                <TextBox.Text>
                                    <Binding Path="P1Text" UpdateSourceTrigger="PropertyChanged">
                                        <Binding.ValidationRules>
                                            <UiUtilities:NumberRule />
                                        </Binding.ValidationRules>
                                    </Binding>
                                </TextBox.Text>
                            </TextBox>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Header2">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate DataType="UserInterface:SomeType">
                        <Grid>                          
                            <TextBox Visibility="{Binding Converter={StaticResource VisibleIfOfTypeX}}">
                                <TextBox.Text>
                                    <Binding Path="P2Text" UpdateSourceTrigger="PropertyChanged">
                                        <Binding.ValidationRules>
                                            <UiUtilities:NumberRule />
                                        </Binding.ValidationRules>
                                    </Binding>
                                </TextBox.Text>
                            </TextBox>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Header3">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate DataType="UserInterface:SomeType">
                        <Grid>                                                        <TextBox Visibility="{Binding Converter={StaticResource VisibleIfOfTypeX}}">
                                <TextBox.Text>
                                    <Binding Path="P3Text" UpdateSourceTrigger="PropertyChanged">
                                        <Binding.ValidationRules>
                                            <UiUtilities:NumberRule />
                                        </Binding.ValidationRules>
                                    </Binding>
                                </TextBox.Text>
                            </TextBox>
                        </Grid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>
    </DataGrid>

</Window>

I'm still a beginner in WPF, but I assume there must be a less verbose way to implement this. I imagine there must be some sort of "templating" or components as they are used in other UI Frameworks. Could we create some sort of component (I call it "MyCustomDataGridColumn"), that we could use like this:

<DataGrid ItemsSource="{Binding DataModel}">

    <DataGrid.Columns>

        <MyCustomDataGridColumn Header="Header1" TextBoxBinding="P1Text">
        <MyCustomDataGridColumn Header="Header2" TextBoxBinding="P2Text">
        <MyCustomDataGridColumn Header="Header3" TextBoxBinding="P3Text">
      
    </DataGrid.Columns>
</DataGrid>

How could we achieve this? Or are there other/better ways to reduce verbosity?

c#

wpf

xaml

datagrid

0 Answers

Your Answer

Accepted video resources