2010-06-03 98 views
5

我綁定PrintQueueItemSourceComboBox(這工作正常)的PageMediaSize集合。然後我將ComboBoxSelectedItem綁定到PrintQueueDefaultPrintTicket.PageMediaSize。雖然這會將所選值設置爲DefaultPrintTicket.PageMediaSize,但它並未將ComboBox的初始值設置爲初始值DefaultPrintTicket.PageMediaSize這是因爲DefaultPrintTicket.PageMediaSize引用與集合中的任何引用都不匹配。不過,我不希望它通過引用比較對象,而是通過值來比較,但PageMediaSize不會覆蓋等於(並且我無法控制它)。我真的很想爲ComboBox設置一個IComparable來使用,但我沒有看到任何方式來做到這一點。我嘗試過使用Converter,但我需要的不僅僅是價值,而且我也不知道如何將收集傳遞給ConverterProperty。關於如何處理這個問題的任何想法。WPF綁定到組合框SelectedItem當參考不在ItemsSource

這裏是我的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中選擇一些內容時,它肯定會設置這個值,但它似乎沒有反過來。

回答

1

是否可以創建一個包裝類PageMediaSize並覆蓋此包裝類中的Equals(object)方法?然後,您可以將此包裝類的實例添加到您的集合中,以便不再通過引用進行比較。當然,你需要一些代碼來打包和解包你的實例,但這是我能想象的最好的方式。

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和選定的項目。

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