WPF: Может ли контент DataGridCell быть установлен через MultiValueConverter? - PullRequest
1 голос
/ 04 августа 2011

У меня есть сетка данных, в которой есть несколько статических и более динамически генерируемых столбцов. Фоновое изображение ячеек динамически добавляемых столбцов успешно настраивается с помощью многозначного преобразователя. Теперь мне нужно добавлять контент в эти ячейки, а не только менять их фон. Я надеялся, что использование многозначного преобразователя для этой цели будет работать, но это не сработало. В отладчике запускается MultiValueConverter, он возвращается со строкой, но ячейки остаются пустыми.

Пожалуйста, смотрите код, где работает настройка Backround, но настройка Content не работает. По сути, они представляют собой один и тот же код за исключением того, что gridCellBgConverter возвращает Brush, gridCellContentConverter возвращает строку.

<DataGrid DockPanel.Dock="Top" Name="main_dg" HorizontalAlignment="Stretch" HorizontalScrollBarVisibility="Hidden" Margin="3"
AutoGenerateColumns="False" SelectionMode="Single" SelectionUnit="Cell" 
SelectedCellsChanged="main_dg_SelectedCellsChanged" CanUserReorderColumns="False" 
CanUserAddRows="False" CellEditEnding="main_dg_CellEditEnding" KeyUp="main_dg_KeyUp" 
FontSize="14" FontWeight="Normal" FontStretch="Normal" SnapsToDevicePixels="True" TextOptions.TextFormattingMode="Display" RenderOptions.EdgeMode="Aliased">
<DataGrid.Resources>
    <Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
        <Setter Property="Padding" Value="-2"/>
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</DataGrid.Resources>
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Background">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource gridCellBgConverter}" UpdateSourceTrigger="PropertyChanged">
                        <MultiBinding.Bindings>
                            <Binding RelativeSource="{RelativeSource Self}"></Binding>
                            <Binding Path="." UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.SelectedStationIndex" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.TrainOnTrackElementId" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.LastStationCountDownChanged" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.SelectedStationDelay" UpdateSourceTrigger="PropertyChanged"></Binding>
                        </MultiBinding.Bindings>
                    </MultiBinding>
                </Setter.Value>
            </Setter>
            <Setter Property="Content">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource gridCellContentConverter}" UpdateSourceTrigger="PropertyChanged">
                        <MultiBinding.Bindings>
                            <Binding RelativeSource="{RelativeSource Self}"></Binding>
                            <Binding Path="." UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.SelectedStationIndex" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.TrainOnTrackElementId" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.LastStationCountDownChanged" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.SelectedStationDelay" UpdateSourceTrigger="PropertyChanged"></Binding>
                        </MultiBinding.Bindings>
                    </MultiBinding>
                </Setter.Value>
            </Setter>                                            
        </Style>
    </DataGrid.CellStyle> 

Является ли внутреннее свойство WPF тем, что Content нельзя установить с помощью Style и ValueConverter? У вас есть идеи, как это решить?

Заранее спасибо: Ференц

Вид решения

С помощью AngelWPF мне удалось решить мою задачу:

  1. динамически создаваемый тип столбцов - DataGridTemplateColoumn

  2. Установщик стиля:

    <Setter Property="ContentTemplate">
    <Setter.Value>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock>
                    <TextBlock.Text>                                                   
                    <MultiBinding Converter="{StaticResource gridCellContentConverter}" UpdateSourceTrigger="PropertyChanged">
                        <MultiBinding.Bindings>
                            <Binding RelativeSource="{RelativeSource Self}"></Binding>
                            <Binding Path="." UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.SelectedStationIndex" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.TrainOnTrackElementId" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.LastStationCountDownChanged" UpdateSourceTrigger="PropertyChanged"></Binding>
                            <Binding Path="TrainToAnnounceViewModel.SelectedStationDelay" UpdateSourceTrigger="PropertyChanged"></Binding>
                        </MultiBinding.Bindings>
                    </MultiBinding>
                </TextBlock.Text>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </Setter.Value>
    

и в MultiValueConverter вместо

public object Convert(object[] values,
       Type targetType, object parameter,
       CultureInfo culture) {
         var cell = (DataGridCell)values[0];

мне пришлось использовать

public object Convert(object[] values,
       Type targetType, object parameter,
       CultureInfo culture) {
          var textBlock = (TextBlock)values[0];
          var cell = (DataGridCell)((ContentPresenter)textBlock.TemplatedParent).TemplatedParent

доступ к исходной ячейке. Я не сомневаюсь, что для этого есть более подходящие методы, но это работает:)

1 Ответ

0 голосов
/ 04 августа 2011

Предполагая, что ваша сетка данных доступна только для чтения (не редактируется), это может быть реализовано, как показано ниже.

(приведенный ниже код не проверен)

      <Style TargetType="{x:Type DataGridCell}">
          <Setter Property="Template">
              <Setter.Value>
                  <ControlTemplate TargetType="{x:Type DataGridCell}">
                      <Border Background="Transparent" 
                    BorderBrush="{TemplateBinding BorderBrush}"  
                    BorderThickness="0" 
                    SnapsToDevicePixels="True">
                          <TextBlock>
                              <TextBlock.Text>
                                <!-- Your MultiBinding Here -->
                              </TextBlock.Text>
                          </TextBlock> 
                      </Border>
                  </ControlTemplate>
              </Setter.Value>
          </Setter>
      </Style>

Предупреждение об этом подходевы теряете многие функции уровня ячеек, такие как проверка, режим редактирования, цвет фона, наведение мыши, цвет выделения и т. д. *

Я все еще рекомендую использовать столбцы DataGridTemplate и свойство CellTemplate.

...