如何根据代码中的对象类型设置数据模板绑定?

How to set Datatemplate binding based on object type from code?

不要问为什么,但我必须在代码的业务逻辑部分创建一个 WPF Listview(原因是我正在处理遗留代码,这就是原因。)

无论如何,到目前为止一切正常,但是,我想添加一个名为“PermutationItem”的复选框列,其中只有一些项目具有相应的 属性。如果 属性 没有 属性(= 类型错误),我想自动将复选框的 IsEnabled 标志设置为 false。 这是到目前为止的代码:

ListView lvPlatformList = new ListView()
{
    Name = "MyListView"
};
lvPlatformList.BorderThickness = new Thickness(1);
lvPlatformList.Margin = new Thickness(0, HeightMargin, 25, HeightMargin);
var gridView = new GridView();

DataTemplate dtEnabled = new DataTemplate() { DataType = typeof(CheckBox) };
FrameworkElementFactory cbfEnabled = new FrameworkElementFactory(typeof(CheckBox));
cbfEnabled.SetBinding(CheckBox.IsCheckedProperty, new Binding("IsEnabled"));
dtEnabled.VisualTree = cbfEnabled;
gridView.Columns.Add(new GridViewColumn()
{
    Header = "Enabled",
    CellTemplate = dtEnabled
});

gridView.Columns.Add(new GridViewColumn()
{
    Header = "Equipment Name",
    DisplayMemberBinding = new Binding("Equipment.Name")
    {
        FallbackValue = "Empty Platform"
    },
});

DataTemplate dtPermutationItem = new DataTemplate() { DataType = typeof(CheckBox) };
FrameworkElementFactory cbfPermutationItem = new FrameworkElementFactory(typeof(CheckBox));
cbfPermutationItem.SetBinding(CheckBox.IsCheckedProperty, new Binding("Equipment.IsPermutationItem.Value")
{
    FallbackValue = false
});
cbfPermutationItem.SetBinding(CheckBox.IsEnabledProperty, /* What comes here?? */);
dtPermutationItem.VisualTree = cbfPermutationItem;
gridView.Columns.Add(new GridViewColumn()
{
    Header = "PermutationItem",
    CellTemplate = dtPermutationItem
});
lvPlatformList.View = gridView;

我知道如何在 XAML 中解决这个问题,但是如何在代码中解决这个问题?

我能够使用带有新 IValueConverter class 的单独绑定来解决它。我使用 Visibility 属性 而不是 IsEnabled,但同样的过程适用于任何 属性。

这是新的 Bindig:

cbfPermutationItem.SetBinding(CheckBox.VisibilityProperty, new Binding("Equipment")
{
    Converter = new DataTypeToVisibilityConverter(),
    ConverterParameter = typeof(MyTargetClass)
});

这是相应的可见性转换器:

public class DataTypeToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Visibility.Hidden;

        Type compareType = parameter as Type;
        Type valueType = value.GetType();

        if (compareType.IsAssignableFrom(valueType))
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Hidden;
        }

    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

您显然可以将任何您想要的内容放入转换器中,但是这里需要注意的是,在我的例子中需要 IsAssignableFrom() 函数来处理继承类型。