简体   繁体   English

当CustomControl DataGrid(WPF Datagrid)中的AutoGenerateColumns = false时,DataGrid.Columns中提到的列不可见

[英]Columns mentioned in DataGrid.Columns is not visible when AutoGenerateColumns=false in CustomControl DataGrid (WPF Datagrid)

I am trying to Create a Custom Control by extending the DataGrid in WPF, but the problem is that when I use this custom control in view and Provide the specific columns by setting the AutoGenerateColumns to False, the columns is not getting generated. 我试图通过在WPF中扩展DataGrid来创建自定义控件,但是问题是,当我在视图中使用此自定义控件并通过将AutoGenerateColumns设置为False提供特定列时,不会生成这些列。 In the OnApplyTemplate() when I tried to fetch the Datagrid through the Template it shows as column count as 0, whereas in the view in code behind it shows the no of columns correctly whatever is specified in the xaml. 在OnApplyTemplate()中,当我尝试通过模板获取Datagrid时,其列数显示为0,而在后面的代码视图中,它正确显示了xaml中指定的列数。 Where I am wrong or something extra needs to be set for this? 如果我错了,或者需要为此设置一些额外的内容?

My Custom control code- 我的自定义控制代码-

public class DataGridControl: DataGrid
 {
    static DataGridControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridControl), new FrameworkPropertyMetadata(typeof(DataGridControl)));
    }

   public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        DataGrid dataGrid = Template.FindName("PART_DataGrid", this) as DataGrid;
        int noOfColumns = dataGrid.Columns.Count// (0 it should come as 3)
    }

}

Generic.xaml(inside the Control Template and border) Generic.xaml(在控制模板和边框内)

 <ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
.....
xmlns:local="clr-namespace:Siemens.WPF.DataGridControl">
<LinearGradientBrush x:Key="lightBrushBack" EndPoint="0.5,1" StartPoint="0.5,0">
    .....
</LinearGradientBrush>

<LinearGradientBrush x:Key="normalBrushBack" EndPoint="0.5,1" StartPoint="0.5,0">
   ......
</LinearGradientBrush>

<Style TargetType="{x:Type local:DataGridControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:DataGridControl}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <DataGrid x:Name="PART_DataGrid"

                                  ItemsSource="{TemplateBinding ItemsSource}"
                                   AutoGenerateColumns="{TemplateBinding AutoGenerateColumns}">
                            <DataGrid.Resources>

                                <!--A custom DataGridColumnHeadersPresenter is required to "not" display the custom ColumnHeader template as background of the datagrid header-->
                                <Style TargetType="{x:Type DataGridColumnHeadersPresenter}">
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
                                                <Grid>
                                                    <!--"part_fillercolumnheader" (DataGridColumnHeader type) is removed, and a plain rectangle is placed in its place.-->
                                                    <Rectangle  Fill="{StaticResource normalBrushBack}" />
                                                    <!--Leave the item presenter in its place.-->
                                                    <ItemsPresenter x:Name="itemsPresenter" />
                                                </Grid>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                                <!--End of custom DataGridColumnHeadersPresenter template-->

                                <!--Custom Column Header Gripper styling-->
                                <Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}">
                                    <Setter Property="Width" Value="3"/>
                                    <Setter Property="Foreground" Value="Transparent" />
                                    <Setter Property="Cursor" Value="SizeWE"/>
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="{x:Type Thumb}">
                                                <Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}"/>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>

                                <!--Custom Column Header template to show extra elements in the header-->
                                <Style TargetType="{x:Type DataGridColumnHeader}">
                                    <Setter Property="FontWeight" Value="Bold" />
                                    <Setter Property="HorizontalContentAlignment" Value="Center" />
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">

                                                <!--Let's keep the top section grid to contain the DataGridHeaderBorder, and left+right thumbs.-->
                                                <Grid x:Name="fullHeader" Background="{StaticResource normalBrushBack}">

                                                    <!--Here is the theme based DataGridHeaderBorder. I've used Aero here.-->
                                                    <aero:DataGridHeaderBorder x:Name='HeaderBorder'
                                                           SortDirection="{TemplateBinding SortDirection}"
                                                           IsHovered="{TemplateBinding IsMouseOver}"
                                                           IsPressed="{TemplateBinding IsPressed}"
                                                           IsClickable="{TemplateBinding CanUserSort}"
                                                           BorderThickness="0,0,1,1"
                                                           BorderBrush="{TemplateBinding Foreground}"
                                                           Background="Transparent"
                                                           SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
                                                           SeparatorBrush="#FFC9CACA">

                                                        <!--Put 3 elements inside the border: Content of header, a drop down button, and a sort order indicator.-->
                                                        <Grid Margin="0,0,0,0">
                                                            <Grid.RowDefinitions>
                                                                <RowDefinition MinHeight="15" Height="20" />
                                                            </Grid.RowDefinitions>
                                                            <Grid.ColumnDefinitions>
                                                                <!--For ContentPresenter-->
                                                                <ColumnDefinition Width="*" />
                                                                <!--For drop down button-->
                                                                <ColumnDefinition Width="23" />
                                                                <!--For sort order indicator-->
                                                                <ColumnDefinition Width="12" />
                                                            </Grid.ColumnDefinitions>

                                                            <!--A hidden rectangle is placed to be shown when mouse hovers on the column (to highlight the column.)-->
                                                            <Rectangle x:Name="HoverRectangle"
                                                                    Stretch="Fill"
                                                                    Grid.ColumnSpan="3"
                                                                    Fill="{StaticResource lightBrushBack}"
                                                                    Opacity="0"
                                                                    StrokeThickness="0" />

                                                            <!--Content of the header.-->
                                                            <ContentPresenter Grid.Column="0" 
                                                                              Grid.Row="0"
                                                                              Margin="2,0,0,0"
                                                                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                                                  VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                                                  HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                                                  Cursor="{TemplateBinding Cursor}" />

                                                            <!--A drop down filter button.-->
                                                            <Button x:Name="PART_FilterBtn" 
                                                                    HorizontalAlignment="Right"
                                                                    Command="{Binding FilterClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
                                                                    CommandParameter="{Binding ElementName=HeaderBorder}"
                                                                    Grid.Row="0" Cursor="Hand"
                                                                    Grid.Column="1">
                                                                <Button.Template>
                                                                    <ControlTemplate>
                                                                        <Path Data="M 0,0 L 1,1 1,3 2,3 2,1 3,0 Z"
                                                                              Stretch="UniformToFill"
                                                                              Stroke="{TemplateBinding Foreground}"
                                                                              Fill="{TemplateBinding Foreground}"
                                                                              Margin="4,4,0,4"/>
                                                                    </ControlTemplate>
                                                                </Button.Template>
                                                            </Button>

                                                            <Path x:Name="PART_SortArrow"
                                                                  Grid.Column="2"
                                                                  HorizontalAlignment="Center" VerticalAlignment="Center" 
                                                                  Width="8"
                                                                  RenderTransformOrigin=".5,.5"
                                                                  Visibility="Visible"
                                                                  Fill="{TemplateBinding Foreground}"
                                                                  Stretch="Uniform"
                                                                  Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z">
                                                            </Path>

                                                        </Grid>
                                                    </aero:DataGridHeaderBorder>

                                                    <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}" />
                                                    <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}" />
                                                </Grid>

                                                <ControlTemplate.Triggers>

                                                    <Trigger Property="SortDirection" Value="Descending">
                                                        <Setter TargetName="PART_SortArrow" Property="RenderTransform">
                                                            <Setter.Value>
                                                                <RotateTransform Angle="180" />
                                                            </Setter.Value>
                                                        </Setter>
                                                    </Trigger>

                                                    <Trigger Property='IsMouseOver' SourceName="fullHeader" Value='True'>
                                                        <Trigger.EnterActions>
                                                            <BeginStoryboard>
                                                                <Storyboard>
                                                                    <DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.20000"
                                                                 Storyboard.TargetName="HoverRectangle"
                                                                 Storyboard.TargetProperty="(UIElement.Opacity)"
                                                                 To='1.0' />
                                                                </Storyboard>
                                                            </BeginStoryboard>
                                                        </Trigger.EnterActions>
                                                        <Trigger.ExitActions>
                                                            <BeginStoryboard>
                                                                <Storyboard>
                                                                    <DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.20000"
                                                                 Storyboard.TargetName="HoverRectangle"
                                                                 Storyboard.TargetProperty="(UIElement.Opacity)"
                                                                 To='0' />
                                                                </Storyboard>
                                                            </BeginStoryboard>
                                                        </Trigger.ExitActions>
                                                    </Trigger>
                                                </ControlTemplate.Triggers>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
                                            <Setter Property="Background">
                                                <Setter.Value>
                                                    <LinearGradientBrush options:Freeze="True" StartPoint="0.504,0.03" EndPoint="0.504,1.5">
                                                        <GradientStop Offset="0.0" Color="#E3F7FF" />
                                                        <GradientStop Offset="0.3" Color="#E3F7FF" />
                                                        <GradientStop Offset="0.35" Color="#BCECFE" />
                                                        <GradientStop Offset="1.0" Color="#B9E9FC" />
                                                    </LinearGradientBrush>
                                                </Setter.Value>
                                            </Setter>
                                            <Setter Property="BorderBrush" Value="#69BBE3" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                                <!--End of custom DataGridColumnHeader template-->

                            </DataGrid.Resources>
                        </DataGrid>
                        <Popup x:Name="PART_PopUp" 
                                Grid.Column="3"
                                AllowsTransparency="True" 
                                AllowDrop="True" 
                                Width="200"
                                Height="253"
                                MinHeight="253"
                                MaxHeight="253"
                                PopupAnimation="Slide"
                                VerticalOffset="-15"
                                IsOpen="{Binding IsFilterPopUpVisible,RelativeSource={RelativeSource AncestorType=local:DataGridControl}}"
                                PlacementTarget="{Binding ElementName=PART_FilterBtn}"
                                StaysOpen="False"
                                Placement="Mouse" >
                            <Border Background="White" BorderBrush="DarkGray" BorderThickness="2">
                                <StackPanel Orientation="Vertical">
                                    <StackPanel Orientation="Horizontal" Margin="10,5,0,5">
                                        <Button Margin="10,0,0,0" Name="PART_SelectAllBtn" Command="{Binding SelectAllClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" CommandParameter="{Binding ElementName=PART_ListBox}" >
                                            <Button.Template>
                                                <ControlTemplate>
                                                    <TextBlock Text="Select All" Foreground="Blue" Cursor="Hand" />
                                                </ControlTemplate>
                                            </Button.Template>
                                        </Button>
                                        <Button Margin="30,0,0,0" Name="PART_SelectNoneBtn" Command="{Binding SelectNoneClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" CommandParameter="{Binding ElementName=PART_ListBox}" >
                                            <Button.Template>
                                                <ControlTemplate>
                                                    <TextBlock Text="Select None" Foreground="Blue" Cursor="Hand" />
                                                </ControlTemplate>
                                            </Button.Template>
                                        </Button>
                                    </StackPanel>
                                    <TextBox x:Name="PART_TextBox" Width="185" Height="25" Text="" Margin="3,0,3,3"/>
                                    <ListBox x:Name="PART_ListBox" 
                                             Height="160" 
                                             MaxHeight="160" 
                                             MinHeight="160" 
                                             Width="185" 
                                             SelectionMode="Multiple" 
                                             DisplayMemberPath="Value"
                                             HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                                             HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                             VerticalAlignment="{TemplateBinding VerticalAlignment}"
                                             VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                             ItemsSource="{Binding FilterCollectionList, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" Margin="0,0,0,5" 
                                             ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible">
                                        <ListBox.ItemContainerStyle>
                                            <Style TargetType="{x:Type ListBoxItem}">
                                                <Setter Property="OverridesDefaultStyle" Value="true" />
                                                <Setter Property="SnapsToDevicePixels" Value="true" />
                                                <Setter Property="HorizontalContentAlignment" Value="Left"/>
                                                <Setter Property="VerticalContentAlignment" Value="Center"/>
                                                <Setter Property="Template">
                                                    <Setter.Value>
                                                        <ControlTemplate TargetType="ListBoxItem" >
                                                            <CheckBox x:Name="PART_CheckBox" Margin="5,2" IsChecked="{Binding IsSelected}">
                                                                <i:Interaction.Triggers>
                                                                    <i:EventTrigger EventName="Checked">
                                                                        <i:InvokeCommandAction Command="{Binding CheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"/>
                                                                    </i:EventTrigger>
                                                                    <i:EventTrigger EventName="Unchecked">
                                                                        <i:InvokeCommandAction Command="{Binding CheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"/>
                                                                    </i:EventTrigger>
                                                                </i:Interaction.Triggers>
                                                                <ContentPresenter />
                                                            </CheckBox>
                                                        </ControlTemplate>
                                                    </Setter.Value>
                                                </Setter>
                                            </Style>
                                        </ListBox.ItemContainerStyle>
                                    </ListBox>
                                    <StackPanel Orientation="Horizontal" Margin="0,0,0,15" HorizontalAlignment="Center">
                                        <Button x:Name="PART_OkBtn" Height="22" Width="70" Content="Ok" 
                                                                                    IsEnabled="{Binding IsOkButtonEnabled, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
                                                                                    Command="{Binding OkButtonClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
                                                                                     />
                                        <Button x:Name="PART_CancelBtn" Height="22" Width="70" Content="Cancel" Margin="5,0,0,0" 
                                                                                    Command="{Binding CancelButtonClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" 
                                                                                    />
                                    </StackPanel>
                                </StackPanel>
                            </Border>
                        </Popup>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

MainWindow.xaml MainWindow.xaml

 <dataGrid:DataGridControl x:Name="dataGridControl" AutoGenerateColumns="False">
        <dataGrid:DataGridControl.Columns>
            <DataGridTextColumn Header="RollNo" Binding="{Binding RollNo}" />
            <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
            <DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}" />
        </dataGrid:DataGridControl.Columns>
    </dataGrid:DataGridControl>

MainWindow.xaml.cs MainWindow.xaml.cs

public MainWindow()
    {
        InitializeComponent();
        List<Student> studList =
        new List<Student>() {  new Student {  RollNo = 1, Name = "Full Name 
        1", FirstName = "FirstName1", LastName="LastName1", Address = 
        "Pune1", PinCode= "411057"},};

        dataGridControl.ItemsSource = studList; 
         int noOfColumns = dataGridControl.Columns.Count; //(showing 3 as expected)
    }

在此处输入图片说明

在此处输入图片说明

Create property for custom control 创建用于自定义控件的属性

 #region GridColumns

 private ObservableCollection<DataGridColumn> _gridColumns;
 public ObservableCollection<DataGridColumn> GridColumns
 {
     get => _gridColumns;
 }

 #endregion GridColumns

Add columns from created property using method OnApplyTemplate 使用OnApplyTemplate方法从创建的属性添加列

 public override void OnApplyTemplate()
 {
     base.OnApplyTemplate();

     if (!AutoGenerateColumns)
     {
         var grid = GetTemplateChild("PART_Grid") as DataGrid;
         foreach (var column in _gridColumns)
             grid.Columns.Add(column);
     }
 }

Change MainWindow.xaml 更改MainWindow.xaml

<dataGrid:DataGridControl x:Name="dataGridControl" AutoGenerateColumns="False">
    <dataGrid:DataGridControl.GridColumns>
        <DataGridTextColumn Header="RollNo" Binding="{Binding RollNo}" />
        <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
        <DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}" />
    </dataGrid:DataGridControl.GridColumns>
</dataGrid:DataGridControl>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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