繁体   English   中英

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

[英]WPF binding to ComboBox SelectedItem when reference not in ItemsSource

我将PrintQueuePageMediaSize集合绑定到ComboBoxItemSource (这很好)。 然后我将ComboBoxSelectedItem绑定到PrintQueueDefaultPrintTicket.PageMediaSize 虽然这会将选定的值设置为DefaultPrintTicket.PageMediaSize就好了,它没有将ComboBox的初始选择值设置为DefaultPrintTicket.PageMediaSize的初始值这是因为DefaultPrintTicket.PageMediaSize引用与之中的任何引用都不匹配采集。 但是我不希望它通过引用来比较对象,而是通过值来比较,但是PageMediaSize不会覆盖Equals(我无法控制它)。 我真正想做的是设置一个IComparableComboBox使用,但我没有看到任何方法。 我曾尝试使用Converter ,但我需要的不仅仅是值,我无法弄清楚如何将集合传递给ConverterProperty 关于如何处理这个问题的任何想法。

这是我的xaml

<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集合的转换器的代码

public class PrintQueueToPageSizesConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
                          System.Globalization.CultureInfo culture)
    {
        return value == null ? null :
            ((PrintQueue)value).GetPrintCapabilities().PageMediaSizeCapability;
    }

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

编辑

我尝试将DefaultPrintTicket.PageMediaSize设置为InitializeComponent之前的集合中的相应引用,但这不起作用。 当我从ComboBox选择某些内容时,它肯定会设置该值,但它似乎没有其他方式。

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

根据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" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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