Как повторно использовать пользовательский код столбца сетки данных в WPF?

Используя VS 2010, я планирую создать несколько столбцов шаблона таблицы данных, но все они будут содержать текстовый блок, и я хочу, чтобы они вели себя как текстовый столбец с точки зрения сортировки, фильтрации, редактирования и т. Д. (Например, столбец, который имеет textblock и изображение внутри стековой панели, но с точки зрения поведения это действительно должно быть связано с текстом.)

При использовании столбца шаблона я узнал, что большая часть функциональности, связанной с обычной текстовой ячейкой, должна быть переделана. Например, чтобы сделать текст редактируемым, необходимо предоставить шаблон редактирования ячейки, например:

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

(И вы также должны обрабатывать события сетки, чтобы убедиться, что он ведет себя как обычное текстовое поле, например, автоматически начинает режим редактирования, если пользователь нажимает клавишу, или вкладки в ячейку и т. Д.)

Поэтому мой вопрос заключается в том, каков наилучший способ (если таковой имеется) для меня, чтобы избежать необходимости явно писать этот код (а также код для сортировки, копирования, фильтрации и т. Д., Как текстовую ячейку, для КАЖДОГО столбца шаблона, который я создаю так " Я предполагаю, что это плохая практика - воспроизводить код на половину страницы для каждого столбца, где единственными отличиями могут быть имя связанного свойства и несколько визуальных изменений.

Я вне этого разочарован и вообще с WPF. Я искал в Интернете, я пробовал украшения, я пытался унаследовать столбец сетки данных, я пытался определить пользовательские элементы управления для шаблонов данных, и все кажется неудачным с некоторой неприятной "ошибкой". Это третий вопрос, который я задавал по этому поводу с различными деталями, с минимальным ответом. НЕ ДОЛЖНО быть таким сложным, чтобы понять, как реализовать те, что в основном представляют собой прославленные текстовые столбцы, без необходимости заново изобретать все колесо каждый раз и во всех отношениях. По моему скромному мнению, по крайней мере.

2 ответа

Решение

Можете ли вы показать мне, как использовать стили ячеек, чтобы изменить существующий 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 Property определить его в DataGridTextColumnили даже 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;
        }
    }

Создайте проект библиотеки, добавьте код и разметку, а также ссылку на эту новую DLL из проектов.

Другие вопросы по тегам