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

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

问题描述:

使用VS 2010,我计划创建几个datagrid模板列,但是它们都将包含一个文本块,并且我希望它们在排序,过滤,编辑等方面表现得像文本列.(例如,一个列在堆栈面板中有一个文本块和一个图像,但是从行为角度来看,它实际上应该全部与文本有关.)

Using VS 2010 I plan to make several datagrid template columns, but they will all contain a textblock and I want to them to behave like a text column in terms of sorting, filtering, editing, etc. (For example, a column that has a textblock and an image within a stackpanel, but behavior-wise it should really be all about the text.)

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

When using a template column, I've learned that much of the functionality associated with a normal text cell must be redone. For instance, in order to make the text editable, one must provide a cell editing template like:

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

(并且,您还必须处理网格事件,以确保其行为类似于普通的文本框,例如,如果用户按下某个键或进入该单元格的制表符,则自动开始编辑模式)

(And you must also handle grid events in order to make sure it behaves like a normal textbox, like automatically beginning edit mode if the user presses a key down, or tabs to the cell, etc.)

所以我的问题是,对于我来说,避免显式编写此代码(以及用于排序,复制,过滤,像文本单元格一样,对于我创建的每个模板列,都是这样?我假设为每列复制一半页面的代码是一种不好的做法,其中唯一的区别可能是绑定的属性名称和少数几个视觉改变.

So my question is, what is the best way (if any) for me to avoid having to explicitly write this code (as well as the code for sorting, copying, filtering, etc like a textcell, for EVERY template column I create like this? I'm assuming it's bad practice to be reproducing half a page's worth of code for each column, where the only differences might the binded property name and a handful of visual alterations.

对此,以及对WPF的使用,我感到无比沮丧.我在网上搜索过,尝试过装饰器,尝试过继承datagrid列,尝试过为数据模板定义用户控件,但一切似乎都因某些讨厌的陷阱"而失败.这是关于我问的第三个问题,它的细节各不相同,而响应却最少.很难弄清楚如何实现基本上是美化的文本列,而不必每次都在每个方面重新发明整个*.至少以我的拙见.

I am beyond frustrated with this, and with WPF in general. I've scoured the web, I've tried adorners, I've tried inheriting a datagrid column, I've tried defining user controls for the data templates, and everything seems to fail with some nasty "gotcha". This is about the 3rd question I've asked regarding this with varying details, with minimal response. It should NOT be this hard to figure out how to implement what are basically glorified text columns, without needing to reinvent the entire wheel every single time and in every single respect. In my humble opinion at least.

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

can you show me how use cell styles to modify an existing DataGridTextColumn such that it displays text along with an image next to it?

这里:

 <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 ,并每次都重复使用.

With some more work, you can define these templates and style as Resources in your application and reuse them every time.

关于图像源,您可以使用 Attached属性 DataGridTextColumn 甚至是 Tag 属性中进行定义.

With regards to the image source, you could use an Attached Property to define it in the DataGridTextColumn, or even the Tag property.

具有附加属性的示例:

Example with an attached property:

 <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;
        }
    }