【问题标题】:WPF custom DataGrid control doesn't show anythingWPF 自定义 DataGrid 控件不显示任何内容
【发布时间】:2015-06-16 23:52:32
【问题描述】:

我有一个自定义 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 DataGrid,它会显示 3 列。

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

目标是在需要时使用标志固定并显示列。

【问题讨论】:

    标签: c# wpf xaml datagrid


    【解决方案1】:

    为了使它工作,我实际上必须删除 Property="Template" 部分,现在应用 DataGrid 样式。虽然这感觉像是一种 hack,但很可能需要了解更多关于 DataGrid 样式覆盖的信息。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      相关资源
      最近更新 更多