Home > Software engineering >  How to set Datatemplate binding based on object type from code?
How to set Datatemplate binding based on object type from code?

Time:11-22

Don't ask why, but I have to create a WPF Listview in the business logic part of the code (the reason is I'm dealing with legacy code, thats why.)

Anyway, so far everything works, however, I want to add a checkbox column called "PermutationItem", where only some of the items have the corresponding property. In case a property doesn't have the property (= has the wrong type), I want to set the IsEnabled flag of the Checkbox to false automatically. This is the code so far:

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;

I know how I would solve this in XAML, but how can it be done here in the code?

CodePudding user response:

I was able to solve it using a separate Binding with a new IValueConverter class. Instead of IsEnabled I used the Visibility property, but the same procedure is applicable to any property.

Here is the new Bindig:

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

And here is the corresponding Visibility Converter:

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();
    }
}

You can obviously put whatever you want into the converter, however a thing to note here is that IsAssignableFrom() function was needed in my case to work with inherited types.

  • Related