简体   繁体   中英

Define a custom WPF control with inheritance

I have a simple problem I guess. Basically I have a WPF app, where I use DataGrid control a lot. And everytime I style it the same way (just the data, number of rows and columns are different). So I thought about creating my own control DataGridMatrix which would fill my needs.

The code I wrote for it is as follows:

<UserControl x:Class="StateMachines.UI.Controls.DataGridMatrix"
             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"
             mc:Ignorable="d">
    <DataGrid Width="450"
              RenderTransformOrigin="0.657,1.249"
              ItemsSource="{Binding Path=Logic.DefaultView}" ColumnWidth="*"
              CanUserReorderColumns="False"
              CanUserResizeColumns="False" CanUserAddRows="False" CanUserSortColumns="False"
              CanUserResizeRows="False" Grid.ColumnSpan="1">
        <DataGrid.ColumnHeaderStyle>
            <Style TargetType="{x:Type DataGridColumnHeader}"
                   BasedOn="{StaticResource MetroDataGridColumnHeader}">
                <Setter Property="HorizontalContentAlignment" Value="Center" />
            </Style>
        </DataGrid.ColumnHeaderStyle>
        <DataGrid.RowHeaderStyle>
            <Style TargetType="{x:Type DataGridRowHeader}"
                   BasedOn="{StaticResource MetroDataGridRowHeader}">
                <Setter Property="HorizontalContentAlignment" Value="Center" />
            </Style>
        </DataGrid.RowHeaderStyle>
        <DataGrid.CellStyle>
            <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MetroDataGridCell}">
                <Setter Property="HorizontalContentAlignment" Value="Center" />
                <Style.Triggers>
                    <DataTrigger
                        Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Column.DisplayIndex}"
                        Value="0">
                        <Setter Property="Block.FontWeight" Value="Bold" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.CellStyle>
    </DataGrid>
</UserControl>

So as you can see, I only style it, I don't put any data in it (in XAML). The problem is I can of course put this control in my MainWindow.xaml like this:

<controls:DataGridMatrix x:Name="DataGridTransition"/>

But then, if I want fe change the position (in grid, fe I would like it to be Grid.ColumnSpan="2" instead of Grid.ColumnSpan="1") I can't do that, cuz the DataGrid is in my control, and my control isn't derived from DataGrid` itself (I guess, if it would be derived, then I could do that, like in normal classes, right?).

So finally my question would be: Is there a way to inherit from a standard XAML control in my own UserControl and just style it differently (like here, in my code I would omit the <DataGrid> tag and I would place its arguments in <UserControl> tag + the other things like DataGrid.ColumnHeaderStyle would be placed right below the <UserControl> )?

Create a custom DataGrid instead of a custom UserControl , ie remove the <UserControl> root element from your XAML file ( DataGridMatrix.xaml ) so it looks like this:

<DataGrid    x:Class="WpfApp2.DataGridMatrix"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Width="450"
              RenderTransformOrigin="0.657,1.249"
              ItemsSource="{Binding Path=Logic.DefaultView}" ColumnWidth="*"
              CanUserReorderColumns="False"
              CanUserResizeColumns="False" CanUserAddRows="False" CanUserSortColumns="False"
              CanUserResizeRows="False" Grid.ColumnSpan="1">
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="{x:Type DataGridColumnHeader}"
                   BasedOn="{StaticResource MetroDataGridColumnHeader}">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.RowHeaderStyle>
        <Style TargetType="{x:Type DataGridRowHeader}"
                   BasedOn="{StaticResource MetroDataGridRowHeader}">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
        </Style>
    </DataGrid.RowHeaderStyle>
    <DataGrid.CellStyle>
        <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource MetroDataGridCell}">
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Style.Triggers>
                <DataTrigger
                        Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Column.DisplayIndex}"
                        Value="0">
                    <Setter Property="Block.FontWeight" Value="Bold" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

...and change the base class in the code-behind ( DataGridMatrix.xaml.cs ) from UserControl to DataGrid :

public partial class DataGridMatrix : DataGrid
{
    public DataGridMatrix()
    {
        InitializeComponent();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM