当引用不在ItemsSource中时,WPF绑定到ComboBox SelectedItem

时间:2010-06-03 19:30:10

标签: c# wpf binding combobox

我将PageMediaSize的{​​{1}}集合绑定到PrintQueue的{​​{1}}(这很好)。然后我将ItemSource的{​​{1}}绑定到ComboBox的{​​{1}}。虽然这会将所选值设置为SelectedItem,但它不会将ComboBox的初始选定值设置为初始值DefaultPrintTicket.PageMediaSize这是因为PrintQueue reference与集合中的任何引用都不匹配。但是我不希望它通过引用来比较对象,而是通过值来比较,但是DefaultPrintTicket.PageMediaSize不会覆盖Equals(我无法控制它)。我真正想做的是为ComboBox设置一个DefaultPrintTicket.PageMediaSize来使用,但我认为没有办法做到这一点。我曾尝试使用DefaultPrintTicket.PageMediaSize,但我需要的不仅仅是价值而且我无法弄清楚如何将集合传递给PageMediaSize。关于如何处理这个问题的任何想法。

这是我的xaml

IComparable

转换器的代码获取ComboBox集合

Converter

修改

我尝试将ConverterProperty设置为<ComboBox x:Name="PaperSizeComboBox" ItemsSource="{Binding ElementName=PrintersComboBox, Path=SelectedItem, Converter={StaticResource printQueueToPageSizesConverter}}" SelectedItem="{Binding ElementName=PrintersComboBox, Path=SelectedItem.DefaultPrintTicket.PageMediaSize}" DisplayMemberPath="PageMediaSizeName" Height="22" Margin="120,76,15,0" VerticalAlignment="Top"/> 之前的集合中的相应引用,但这不起作用。当我从PageMediaSize中选择某些内容时,它肯定会设置该值,但它似乎没有反过来。

2 个答案:

答案 0 :(得分:2)

是否可以为PageMediaSize创建包装类并覆盖此包装类中的Equals(object)方法?然后,您可以将此包装类的实例添加到集合中,以便不再通过引用对它们进行比较。当然,您需要一些代码来包装和展开PageMediaSize个实例,但这是我能想象到的最佳方式。

答案 1 :(得分:1)

根据juharr的回答,您可以使用转换器来包装和展开对象。

using System;
using System.Collections;
using System.Globalization;
using System.Linq;
using System.Windows.Data;

namespace MyNameSpace
{
    public class ToTypeEqualityWrapper : IValueConverter
    {
        public class TypeEqualityWrapper
        {
            public object Value { get; set; }

            public TypeEqualityWrapper(object value)
            {
                Value = value;
            }

            public override bool Equals(object obj)
            {
                var otherWrapper = obj as TypeEqualityWrapper;
                if (otherWrapper == null)
                    return false;

                var result = Value.GetType().FullName == otherWrapper.Value.GetType().FullName;
                return result;
            }
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var list = value as IList;
            if (list != null)
            {
                return (from object item in list select new TypeEqualityWrapper(item)).Cast<object>().ToList();
            }

            return new TypeEqualityWrapper(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var wrapper = value as TypeEqualityWrapper;
            if(wrapper != null)
                return wrapper.Value;

            return value;
        }
    }
}

然后声明你的转换器

<ns:ToTypeEqualityWrapper x:Key="toTypeEqualityWrapper" />    

在xaml中,在ItemSource和Selected Item上使用转换器。

<ComboBox                                                               
    ItemsSource="{Binding MySource, Converter={StaticResource toTypeEqualityWrapper}}" 
    SelectedItem="{Binding MySelectedItem, Converter={StaticResource toTypeEqualityWrapper}}"                                                             
    DisplayMemberPath="Value.DisplayName" />