WPF DataGrid 不使用 DataTemplate 和 DataTriggers 显示数据

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

我有视图模型

 public class ViewModel 
 {
    public string TestField { get; set; }  

    public ObservableCollection<object> TestCollection { get; set; }  

    public ViewModel()
    {
        TestField  = "ABCD";
    }
 }

我想根据 TestField 的值使用不同的 DataGridTemplateColumns。 DataGrid 将 TestCollection 作为其 ItemSource,并且在 DataTemplate 中,我想使用 ItemSource 中的项目。不过DataTemplate的选择需要依赖于TestField。 问题在于 TestField 位于 TestCollection 的上下文之外。

c# wpf binding datagrid
1个回答
0
投票

一种解决方案是使用转换器将 TestField 属性绑定到 CellTemplate 属性。
如果 TestField 属性在创建 ViewModel 实例后可以更改,则需要通过 INotifyPropertyChanged.PropertyChanged 事件提供其更改的通知。在我的示例中,这是通过 ViewModelBase 基类的方法完成的:

    public class TestFieldViewModel : ViewModelBase
    {
        public string TestField { get => Get<string>(); set => Set(value); }

        public ObservableCollection<object> TestCollection { get; /*set;*/ } = new();

        public TestFieldViewModel()
        {
            foreach (var item in "Example")
            {
                TestCollection.Add(item);
            }

            // асинхронная смена значения с целью тестирования
            Task.Run(async () =>
            {
                while (true)
                {
                    await Task.Delay(2000);
                    TestField = TestField == "ABCD" ? string.Empty : "ABCD";
                }
            });
        }
    }
    public class TestFieldTemplateConverter : IValueConverter
    {
        public DataTemplate Default { get; set; }
        public DataTemplate ABCD { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value switch
            {
                "ABCD" => ABCD,
                _ => Default
            };
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
<Window ----------------------------
        ----------------------------
        DataContext="{DynamicResource vm}">
    <Window.Resources>
        <local:TestFieldViewModel x:Key="vm"/>
    </Window.Resources>
    <Grid>
        <DataGrid ItemsSource="{Binding TestCollection}">
            <DataGrid.Resources>
                <DataTemplate x:Key="default">
                    <TextBlock Text="Default"/>
                </DataTemplate>
                <DataTemplate x:Key="ABCD">
                    <TextBlock Text="ABCD"/>
                </DataTemplate>
                <local:TestFieldTemplateConverter
                    x:Key="templateConverter"
                    Default="{StaticResource default}"
                    ABCD="{StaticResource ABCD}"/>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTemplateColumn
                    CellTemplate="{Binding TestField,
                                           Source={StaticResource vm},
                                           Converter={StaticResource templateConverter}}">
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
© www.soinside.com 2019 - 2024. All rights reserved.