[英]WPF binding to ComboBox SelectedItem when reference not in ItemsSource
I'm binding the PageMediaSize
collection of a PrintQueue
to the ItemSource
of a ComboBox
(This works fine). 我将
PrintQueue
的PageMediaSize
集合绑定到ComboBox
的ItemSource
(这很好)。 Then I'm binding the SelectedItem
of the ComboBox
to the DefaultPrintTicket.PageMediaSize
of the PrintQueue
. 然后我将
ComboBox
的SelectedItem
绑定到PrintQueue
的DefaultPrintTicket.PageMediaSize
。 While this will set the selected value to the DefaultPrintTicket.PageMediaSize
just fine it does not set the initially selected value of the ComboBox
to the initial value of DefaultPrintTicket.PageMediaSize
This is because the DefaultPrintTicket.PageMediaSize
reference does not match any of the references in the collection. 虽然这会将选定的值设置为
DefaultPrintTicket.PageMediaSize
就好了,它没有将ComboBox
的初始选择值设置为DefaultPrintTicket.PageMediaSize
的初始值这是因为DefaultPrintTicket.PageMediaSize
引用与之中的任何引用都不匹配采集。 However I don't want it to compare the objects by reference, but instead by value, but PageMediaSize
does not override Equals (and I have no control over it). 但是我不希望它通过引用来比较对象,而是通过值来比较,但是
PageMediaSize
不会覆盖Equals(我无法控制它)。 What I'd really like to do is setup a IComparable
for the ComboBox
to use, but I don't see any way to do that. 我真正想做的是设置一个
IComparable
供ComboBox
使用,但我没有看到任何方法。 I've tried to use a Converter
, but I would need more than the value and I couldn't figured out how to pass the collection to the ConverterProperty
. 我曾尝试使用
Converter
,但我需要的不仅仅是值,我无法弄清楚如何将集合传递给ConverterProperty
。 Any ideas on how to handle this problem. 关于如何处理这个问题的任何想法。
Here's my xaml 这是我的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"/>
And the code for the converter that gets the PageMediaSize
collection 以及获取
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();
}
}
Edit 编辑
I tried setting the DefaultPrintTicket.PageMediaSize
to the corresponding reference in the collection before InitializeComponent
, but that did not work. 我尝试将
DefaultPrintTicket.PageMediaSize
设置为InitializeComponent
之前的集合中的相应引用,但这不起作用。 It's definately setting the value when I select something from the ComboBox
, but it doesn't seem to go the other way. 当我从
ComboBox
选择某些内容时,它肯定会设置该值,但它似乎没有其他方式。
Would it be possible to create a wrapper class for PageMediaSize
and override the Equals(object)
method in this wrapper class? 是否可以为
PageMediaSize
创建一个包装类并覆盖此包装类中的Equals(object)
方法? You could then add instance of this wrapper class to your collection, so that they are no longer compared by reference. 然后,您可以将此包装类的实例添加到集合中,以便不再通过引用对它们进行比较。 Of course, you will need some code for wrapping and unwrapping your
PageMediaSize
instances, but that's the best way I can imagine. 当然,您需要一些代码来包装
PageMediaSize
包您的PageMediaSize
实例,但这是我能想象到的最佳方式。
Further to juharr's answer, you could use a converter to wrap and unwrap the object. 根据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;
}
}
}
Then declare your converter 然后声明你的转换器
<ns:ToTypeEqualityWrapper x:Key="toTypeEqualityWrapper" />
In the xaml, use the converter on both ItemSource and Selected Item. 在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.