WPF 自定义数据网格控件不显示任何内容

本文关键字:显示 任何内 控件 网格 自定义 数据 数据网 WPF | 更新日期: 2023-09-27 17:56:37

>我有一个自定义的DataGrid控件。

类如下所示:

    public static class CloneRowDataGridCommands
    {
        private static RoutedCommand _cloneRowRoutedCommand = new RoutedCommand();
        public static RoutedCommand CloneRowRoutedCommand
        {
            get { return _cloneRowRoutedCommand; }
        }
    }
    public class CloneRowDataGrid : DataGrid
    {
        protected Button CloneButton { get; set; }
        public static readonly DependencyProperty ShowCloneColumnProperty =
            DependencyProperty.Register("ShowCloneColumn", 
            typeof(bool),
            typeof(CloneRowDataGrid),
            new FrameworkPropertyMetadata(false, 
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                OnShowCloneColumnPropertyChanged));
        private static void OnShowCloneColumnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CloneRowDataGrid cloneRowDataGrid = d as CloneRowDataGrid;
            if (cloneRowDataGrid != null)
            {
                cloneRowDataGrid.OnShowCloneColumnPropertyChanged((bool) e.OldValue, (bool) e.NewValue);
            }
        }
        protected virtual void OnShowCloneColumnPropertyChanged(bool oldValue, bool newValue)
        {
            // Nothing right now
        }
        public static readonly RoutedEvent CloneEvent =
            EventManager.RegisterRoutedEvent("Clone", RoutingStrategy.Bubble,
                typeof(CloneRowRoutedEventHandler), 
                typeof (CloneRowDataGrid));
        public event CloneRowRoutedEventHandler Clone
        {
            add { AddHandler(CloneEvent, value); }
            remove { RemoveHandler(CloneEvent, value); }
        }
        protected virtual void RaiseCloneEvent()
        {
            // TODO: change "new object()" to the row data
            CloneRowRoutedEventArgs args = new CloneRowRoutedEventArgs(CloneEvent, new object());
            RaiseEvent(args);
        }
        static CloneRowDataGrid()
        {
            DefaultStyleKeyProperty.OverrideMetadata(
                typeof(CloneRowDataGrid), 
                new FrameworkPropertyMetadata(typeof(CloneRowDataGrid)));
        }
        public CloneRowDataGrid()
        {
            CommandBindings.Add(new CommandBinding(CloneRowDataGridCommands.CloneRowRoutedCommand,
                ExecuteCloneRow, CanExecuteCloneRow));
        }
        private void CanExecuteCloneRow(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }
        private void ExecuteCloneRow(object sender, ExecutedRoutedEventArgs e)
        {
            // TODO: Clone row
            RaiseCloneEvent(); // pass object row to the eventargs
        }
        public bool ShowCloneColumn
        {
            get { return (bool) GetValue(ShowCloneColumnProperty); }
            set { SetValue(ShowCloneColumnProperty, value); }
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            // Do stuff
            // TODO: Fix this to avoid memory lick if the event is already registered
            // TODO: Or change to a command for the clone button
            CloneButton = GetTemplateChild("PART_CloneButton") as Button;
            if (CloneButton != null)
            {
                CloneButton.Click += OnCloneButtonClick;
            }
        }
        private void OnCloneButtonClick(object sender, RoutedEventArgs routedEventArgs)
        {
            // Invoke another event that might be registered from the client
            RaiseCloneEvent();
        }
        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            // Do stuff
        }
        protected override void OnColumnDisplayIndexChanged(DataGridColumnEventArgs e)
        {
            base.OnColumnDisplayIndexChanged(e);

        }
    }
    public delegate void CloneRowRoutedEventHandler(object sender, CloneRowRoutedEventArgs e);
    public class CloneRowRoutedEventArgs : RoutedEventArgs
    {
        public object RowObject { get; protected set; }
        public CloneRowRoutedEventArgs(RoutedEvent routedEvent, object rowObject) : base(routedEvent)
        {
            RowObject = rowObject;
        }
    }

Generic.xaml 中的样式如下所示。

<Style TargetType="{x:Type uiControls:CloneRowDataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type uiControls:CloneRowDataGrid}">
                    <!-- Parameter should be the row -->
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

使用控件时。

<uiControls:CloneRowDataGrid ItemsSource="{Binding SomeListCustomers}" AutoGenerateColumns="False" CanUserAddRows="False" x:Name="GridCustom"
                          HorizontalScrollBarVisibility="Disabled" BorderThickness="1" BorderBrush="DimGray" 
                          ColumnHeaderStyle="{StaticResource DataGridColumnHeaderStyle}" Margin="10,0,25,0" Height="200">
                            <DataGrid.CellStyle>
                                <Style TargetType="{x:Type DataGridCell}">
                                    <Setter Property="IsTabStop" Value="False"/>
                                    <Setter Property="Focusable" Value="False"/>
                                </Style>
                            </DataGrid.CellStyle>
                            <DataGrid.Resources>
                                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White"/>
                                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
                                <SolidColorBrush x:Key="{x:Static SystemColors.ActiveBorderColorKey}" Color="White"/>
                            </DataGrid.Resources>
                            <DataGrid.Columns>
                                <StaticResource ResourceKey="CloneRowButtonColumn"/>
                                <DataGridTemplateColumn Header="Name" Width="75" >
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <TextBox Text="{Binding Name}" Width="75" IsReadOnly="True" Focusable="False" IsTabStop="False"/>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                </DataGridTemplateColumn>
                                <DataGridTemplateColumn Header="NickName" Width="100" >
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <TextBox Text="{Binding NickName}" Width="100" IsReadOnly="True" Focusable="False" IsTabStop="False"/>
                                        </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </uiControls:CloneRowDataGrid>

我在设计器和运行时得到的只是一个没有列的灰色边框。如果我在 XAML 窗口中更改类型 tp 数据网格,它会显示 3 列。

我肯定错过了一些东西。我不需要任何特殊的样式,我只需要 DataGrid 外观,然后使用其他功能。

目标是在需要时使用

标志固定和可见列。

WPF 自定义数据网格控件不显示任何内容

为了使它工作,我实际上必须删除属性="模板"部分,现在 DataGrid 样式适用。虽然这感觉像是一个黑客,并且很可能需要了解有关 DataGrid 样式覆盖的更多信息。

<Style TargetType="{x:Type uiControls:CloneRowDataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
</Style>