WPF DataGrid IValueConverter 仅在所选项目更改时触发,而不是在绑定值更改时触发

问题描述 投票:0回答:1

我已经设置了一个带有“操作”列(组合框)的数据网格。我需要确保我的其他两列的背景和读/写能力根据选择的操作而改变。我创建了两个转换器来执行此操作,它们接受整个 DataGridRow 作为上下文,因为我还需要能够从转换器调用 ParentStatus 属性(如果我只接受当前值,则无法访问 ParentStatus)。以下是 XAML 的相关部分:

<DataGrid Grid.Row="1" Grid.Column="0" ItemsSource="{Binding SelectedWcn.Lines}" Style="{StaticResource DataGridStyle}" AutoGenerateColumns="False" IsReadOnly="{Binding IsGridReadOnly}" Margin="2">
<DataGrid.Columns>
    <DataGridTextColumn Header="Part ID" Binding="{Binding PartID}" />
    <DataGridTemplateColumn Header="Action">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox SelectedValue="{Binding Action, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                            ItemsSource="{Binding DataContext.ActionOptions, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
                            DisplayMemberPath="Value"
                            SelectedValuePath="Value"
                            IsEnabled="{Binding Path=. , Converter={StaticResource StatToEnabledConv}, ConverterParameter='Action'}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTemplateColumn Header="QTY Change">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBox Text="{Binding QTYChange, UpdateSourceTrigger=PropertyChanged}"
                            IsReadOnly="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Converter={StaticResource ActToReadOnlyConv}, ConverterParameter=QTY_CHANGE}"
                            Background="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Converter={StaticResource ActToBackConv}, ConverterParameter=QTY_CHANGE}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTemplateColumn Header="Replacement PN">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBox Text="{Binding ReplacementPN, UpdateSourceTrigger=PropertyChanged}"
                            IsReadOnly="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Converter={StaticResource ActToReadOnlyConv}, ConverterParameter=ALTERNATE_PART_ID}"
                            Background="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Converter={StaticResource ActToBackConv}, ConverterParameter=ALTERNATE_PART_ID}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

这是我实现 NotifyPropertyChanged 的模型:

 public class WCN_Line : ObservableObject
{
    private int? _rowID;
    private string __partID;
    private string _action;
    private int? _qtyChange;
    private string _disposition;
    private string? _replacementPN;
    private string _reason;
    private string _note;
    private string? _parentStatus;

    public int WCN_ID { get; set; }
    // ... Other fields

    public string Action
    {
        get => _action;
        set
        {
            if (_action != value)
            {
                _action = value;
                OnPropertyChanged();
                ClearFieldsBasedOnAction();
            }
        }
    }

转换器本身工作完美,但当操作更改时我无法再让它触发。它不会在值更改时触发,而是仅在 SelectedWcn 更改时触发。我已进行调试以确认 a) 我的属性正在更新并通知更改,b) 转换器根本不会在操作更改时触发(而不是触发,但没有执行任何操作)。

编辑-我应该注意 SelectedWcn 是从集合中选择的:ObservableCollection Wcns。 WcnInReview 有一个 WCN_Lines 集合,简称为 Lines,它是网格绑定到的。

我知道它昨天正常工作,所以我一定做了一些我不记得的更改,但我整个早上都对此进行了分析,但找不到问题。

c# wpf data-binding
1个回答
0
投票

转换器仅在数据绑定属性引发

PropertyChanged
事件时才会触发。由于您绑定到
DataContext
,因此当您设置
Action
属性`时,它不会触发。

您可以通过使用

IMultiValueConverter
并绑定到
DataContext
Action
来解决此问题:

<TextBox Text="{Binding QTYChange, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.IsReadOnly>
        <MultiBinding Converter="{StaticResource ActToReadOnlyConv}" ConverterParameter="QTY_CHANGE">
            <Binding Path="DataContext" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" />
            <Binding Path="Action" />
        </MultiBinding>
    </TextBox.IsReadOnly>
</TextBox>

转换器:

public class ActionToReadOnlyConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        WCN_Line line = values[0] as WCN_Line;
        ...
        }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.