【问题标题】:WPF binding to ComboBox SelectedItem when reference not in ItemsSource未在 ItemsSource 中引用时 WPF 绑定到 ComboBox SelectedItem
【发布时间】:2011-02-27 11:43:11
【问题描述】:

我将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 中选择某些内容时,它肯定会设置值,但它似乎并没有相反。

【问题讨论】:

    标签: c# wpf binding combobox


    【解决方案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" />
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2015-06-28
        • 1970-01-01
        • 2010-10-24
        • 2015-04-07
        • 2011-11-01
        • 2016-03-25
        • 2012-09-20
        • 2021-10-18
        • 2017-11-09
        相关资源
        最近更新 更多