简体   繁体   中英

CollectionViewSource Items binding with value converter

In my WPF application, there is a custom value converter where the Convert method receives a ReadOnlyObservableCollection value parameter.

This value converter is called in XAML from the following binding:

<TextBlock Grid.Column="2" Text="{Binding Items, Converter={StaticResource totalCutsConverter}}"/>

Where Items comes from a CollectionViewSource with grouping descriptions difened as:

<CollectionViewSource x:Key="sheetsViewSource" Source="{Binding}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="MaterialDescription" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>

Question is: How can I make my value converter receives a collection of my specific Items type (model class) instead of a generic object class?

In other words, I would like to make the following cast in my Convert method

ReadOnlyObservableCollection<myClass> col = value as  ReadOnlyObservableCollection<myClass>();

Any ideas?

The solution has already been mentioned in the comments, which is to simply convert the value in your converter. There really isn't any need to implement anything fancy for this.

That being said, I challenged myself, and if you're really up for it, then here's an example of how it can be done:

public interface IValueConverter<T> : IValueConverter
{
    object Convert(T value, Type targetType, object parameter, CultureInfo culture);
    object ConvertBack(T value, Type targetType, object parameter, CultureInfo culture);
}

public abstract class GenericConverter<T> : IValueConverter<T>
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        CheckType(value);

        return Convert((T)value, targetType, parameter, culture);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        CheckType(value);

        return ConvertBack((T)value, targetType, parameter, culture);
    }

    private void CheckType(object value)
    {
        if (value == null)
        {
            //TODO: Do something about nulls.
        }

        Type type = typeof(T);

        if (value.GetType() != type)
            throw new InvalidCastException(string.Format("Converter value could not be cast to: ", type.Name));
    }

    public abstract object Convert(T value, Type targetType, object parameter, CultureInfo culture);
    public abstract object ConvertBack(T value, Type targetType, object parameter, CultureInfo culture);
}

Essentially, it's just a normal converter, but with addition type checking and casting on top. Here's an example of how to use it:

public class ExampleConverter : GenericConverter<string>
{
    public override object Convert(string value, Type targetType, object parameter, CultureInfo culture)
    {
        //TODO: Convert implementation

        return value;
    }

    public override object ConvertBack(string value, Type targetType, object parameter, CultureInfo culture)
    {
        //TODO: ConvertBack implementation

        return value;
    }
}

To be honest, it would be much easier to simply cast to your desired value type in your converter, however this is here if you need it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM