如何在WPF中重用自定义datagrid列代码?

时间:2013-07-15 20:46:30

标签: wpf datagrid datagridtemplatecolumn

使用VS 2010我打算制作几个datagrid模板列,但它们都包含一个文本块,我希望它们在排序,过滤,编辑等方面表现得像文本列一样(例如,一列在堆叠面板中有一个文本块和一个图像,但在行为方面它应该完全是关于文本的。)

使用模板列时,我了解到必须重做与普通文本单元格相关的许多功能。例如,为了使文本可编辑,必须提供如下的单元格编辑模板:

<DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <TextBox
        FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
        Text="{Binding Path=SomeProperty, Mode=TwoWay, UpdateSourceTrigger=LostFocus}">
            </TextBox>
    </DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>

您还必须处理网格事件,以确保其行为类似于普通文本框,例如,如果用户按下某个键,则自动开始编辑模式,或者选中标签到单元格等。)

所以我的问题是,对于我来说,避免必须明确编写此代码(以及用于排序,复制,过滤,代码的代码)的最佳方式(如果有的话)是什么?像textcell一样,对于我创建的每个模板列都是这样吗?我假设为每列重现半页的代码是不好的做法,其中唯一的区别可能是绑定的属性名称和少数几个视觉改变。

我对此感到非常沮丧,并且对WPF感到非常沮丧。我已经浏览过网络了,我已经尝试过装饰,我尝试继承数据网格列,我已经尝试为数据模板定义用户控件,而且一切似乎都失败了一些令人讨厌的“陷阱”。这是关于第三个问题,我提出了不同细节的问题,反应最小。它应该 NOT 很难弄清楚如何实现基本上美化的文本列,而不需要每一次和每一个方面重新发明整个轮子。至少在我的拙见中。

2 个答案:

答案 0 :(得分:1)

  

你能告诉我如何使用单元格样式修改现有的DataGridTextColumn,使其显示文本以及旁边的图像吗?

下面:

 <DataGridTextColumn Binding="{Binding LastName}">
     <DataGridTextColumn.CellStyle>
         <Style TargetType="DataGridCell">
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="DataGridCell">
                         <Grid>
                             <Grid.ColumnDefinitions>
                                 <ColumnDefinition/>
                                 <ColumnDefinition Width="16"/>
                             </Grid.ColumnDefinitions>

                             <ContentPresenter ContentSource="Content"/>
                             <Image Source="/Images/Homer.jpg" Grid.Column="1"/>
                        </Grid>
                     </ControlTemplate>
                 </Setter.Value>
             </Setter>
         </Style>
     </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

通过更多工作,您可以在应用程序中将这些模板和样式定义为Resources,并且每次都重复使用它们。

关于图片来源,您可以使用Attached PropertyDataGridTextColumn甚至Tag属性中定义它。

编辑:附加属性的示例:

 <DataGrid ...>
            <DataGrid.Resources>
                <ControlTemplate TargetType="DataGridCell" x:Key="TextAndImageDataGridCellTemplate">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="16"/>
                        </Grid.ColumnDefinitions>

                        <ContentPresenter ContentSource="Content"/>
                        <Image Source="{Binding Column.(local:GridColumnProperties.ImageSource), RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="1"/>
                    </Grid>
                </ControlTemplate>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding LastName}"
                                    local:GridColumnProperties.ImageSource="/Images/Homer.jpg">
                    <DataGridTextColumn.CellStyle>
                        <Style TargetType="DataGridCell">
                            <Setter Property="Template" Value="{StaticResource TextAndImageDataGridCellTemplate}"/>
                        </Style>
                    </DataGridTextColumn.CellStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
    </DataGrid>

代码:

   public static class GridColumnProperties
    {
        public static readonly DependencyProperty ImageSourceProperty = DependencyProperty.RegisterAttached("ImageSource", typeof(ImageSource), typeof(GridColumnProperties), new PropertyMetadata());

        public static void SetImageSource(DependencyObject obj, ImageSource value)
        {
            obj.SetValue(ImageSourceProperty, value);
        }

        public static ImageSource GetImageSource(DependencyObject obj)
        {
            return obj.GetValue(ImageSourceProperty) as ImageSource;
        }
    }

答案 1 :(得分:-2)

创建一个库项目,添加代码和标记,并从项目中引用这个新的dll。