WPF DataGridTextColumn Привязка к весу шрифта / преобразователь значений не работает

#c# #wpf #binding

#c# #wpf #привязка

Вопрос:

Я хорошо понимаю концепцию привязки / преобразователя значений, но по некоторым причинам следующая привязка не работает. Я хотел бы изменить значение FontWeight Bold для некоторых описаний ( Description это текстовое поле):

XAML:

 <DataGridTextColumn Header="Description"
                    Binding="{Binding Description}"
                    FontWeight="{Binding Description, Converter={converters:DescriptionToFontWeightConverter}}"/>
  

Метод преобразования значений (упрощенный):

 public class DescriptionToFontWeightConverter : ConverterMarkupExtension<DescriptionToFontWeightConverter>
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Some logic based on the value
        // ..
        
        return "Bold"; // I believe I should use "Bold", and not "FontWeights.Bold" here (like it would be with a dependency property, but the problem is that it doesn't go inside the method.
    }

    public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => Binding.DoNothing;
}

  

Я считаю, что проблема связана с путем привязки свойства FontWeight. Например, если я заменю (Path=)Description на RelativeSource={RelativeSource Self} , он войдет в метод преобразования значений, но я не думаю, что смогу получить значение привязки.. Я думаю, что это не что-то ненормальное (по крайней мере, то, чего я не ожидал), но мне интересно, не следует ли мне заменить DataGridTextColum на a DataGridTemplateColum и копать дальше?

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

ОБНОВЛЕНИЕ с помощью DataGridColumnTemplate

 <DataGridTemplateColumn Header="Description">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Description}">
                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="FontWeight"
                                Value="{Binding Description, Converter={converters:DescriptionToFontWeightConverter}}"/>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Description}"/>
        </DataTemplate>                    
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
  

Спасибо за любую информацию 🙂

Ответ №1:

A DataGridColumn не наследует никаких DataContext , поэтому попытка привязки к Description свойству текущего элемента всегда завершается неудачей.

Binding Свойство является особенным. Его тип Binding и привязка, которые вы определяете в XAML, в конечном итоге будут применены к элементу, который создается во время выполнения. В случае a DataGridTextColumn это a TextBlock или a TextBox в зависимости от того, находитесь ли вы в режиме редактирования.

но мне интересно, не следует ли мне заменить DataGridTextColumn на DataGridTemplateColumn и копать дальше

Если вы используете a DataGridTemplateColumn и определяете a TextBlock в CellTemplate (и a TextBox в CellEditingTemplate ), вы можете фактически привязаться к свойству текущего элемента, как обычно. Это связано с тем, что элемент в шаблоне добавляется в дерево элементов и наследует a DataContext , как и любой другой элемент.

Комментарии:

1. Хорошо, спасибо. Я внес изменения (см. Обновление), и они отлично работают, но я не уверен, разрешу ли я прямое редактирование. Я действительно не знаю почему, но что-то помешало мне «просто» попробовать..

2. @Or8e4m4n: CellEditingTemplate TextBlock будет показано, что вы находитесь в режиме редактирования, так что это должно сработать.