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). Then I'm binding the SelectedItem
of the ComboBox
to the DefaultPrintTicket.PageMediaSize
of the PrintQueue
. 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. 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). 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. 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
. Any ideas on how to handle this problem.
Here's my 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
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 ConvertB开发者_如何学JAVAack(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. It's definately setting the value when I select something from the ComboBox
, but it doesn't seem to go the other way.
Would it be possible to create a wrapper class for PageMediaSize
and override the Equals(object)
method in this wrapper class? 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.
Further to juharr's answer, you could use a converter to wrap and unwrap the object.
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.
<ComboBox
ItemsSource="{Binding MySource, Converter={StaticResource toTypeEqualityWrapper}}"
SelectedItem="{Binding MySelectedItem, Converter={StaticResource toTypeEqualityWrapper}}"
DisplayMemberPath="Value.DisplayName" />
精彩评论