2010-04-15 56 views
1

我的模板基本上是作爲一個簡單的調色板使用的ComboBox。它填充了一個SolidColorBrush對象的列表。根據匹配對象在XAML中設置ComboBox.SelectedItem

我也有一些數據保存了當前顏色的十六進制值以及將十六進制轉換爲SolidColorBrush的轉換器。

我在嘗試的是根據我的DataSource中的顏色設置ComboBoxSelectedItem屬性。由於我的組合填充了SolidColourBrush類型,對象和我的結合轉換器返回SolidColorBrush,我認爲這將是簡單的話說:

SelectedItem="{Binding Color, Converter={StaticResource StringToBrush}}" 

但是......它不工作:(

我測試過的結合是通過使用完全相同的價值爲ComboBox的背景屬性在幕後工作。

因此,很明顯我不能隨便說的SelectedItem = [東西]這裏是[東西]基本上是一個對象,它等於我想要選擇的項目

這樣做的正確方法是什麼?當然,只有XAML風格的使用綁定纔是可能的,而且我不必爲了查找匹配而嘗試查找組合框中的所有項目來執行一些討厭的C#代碼(這看起來很老派)......?

+0

的建議將是覆蓋''的SolidColorBrush的'Equals'功能。默認情況下,當比較兩個項目時,「Equals」檢查引用是否相同。你可以改變這種行爲,並使「Equals」來檢查例如顏色代碼是否相同。檢查[這個答案](http://stackoverflow.com/a/34140769/2279200)以供參考。 – Athafoud 2016-12-12 11:52:37

回答

0

我正在使用的MVVM模式,則屬性SelectedHexColor添加到您的視圖模型,讓視圖模型搜索您的列表中正確的純色畫筆從被填充的顏色刷組合框和更新的SelectedBrush財產您所選擇的組合框的所選項目所綁定的視圖模型。

我剛剛讀到你想避免C#代碼,因爲你認爲它是老派。但是這是MVVM模式的一個優勢,因爲您可以精確地測試這個已經是複雜業務邏輯的代碼。把它放在XAML中是非常不安全的,因爲你不能單元測試它,因此你不能獲得正確的功能(除了自動UI測試比單元測試更復雜)。

最好的問候,
奧利弗Hanappi

+0

嗯......好的。但我想我正在尋找一個更普遍的答案。如果我有一個帶有Foo類型項目列表的組合框,並且我還有另一個Foo實例在其他位置(比如說,在myFoo中),那麼肯定有一個XAML唯一的方式來說:「組合框的選定項目是myFoo「,或者更確切地說,」組合框的選定項目是與myFoo匹配的Foo「...對吧? – 2010-04-15 13:14:09

+0

在這種情況下,您將需要實現值相等邏輯。爲此,您可以將'SolidColorBrush'封裝在實現值相等的對象中(重寫GetHashCode和Equals)。 – 2010-04-15 13:26:09

1

您可以在組合框數據綁定的SelectedItem。如果我理解了你的描述,你將得到一串十六進制字符串和一個名爲Color的SolidColorBrush屬性。選定項目更改時,下面的代碼更新Color屬性。

XAML:

<Window x:Class="SelItemTest.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:SelItemTest="clr-namespace:SelItemTest" 
    Title="Window1" Height="300" Width="300"> 

    <Window.Resources>   
     <SelItemTest:StringToBrushConverter x:Key="StringToBrush" />   
    </Window.Resources> 

    <StackPanel Background="{Binding Path=Color}"> 
     <ComboBox 
      ItemsSource="{Binding Path=Colors}" 
      SelectedItem="{Binding Path=Color, Converter={StaticResource StringToBrush}}"> 
      <ComboBox.ItemTemplate> 
       <DataTemplate> 
        <Border Background="{Binding}" Height="20" Width="100" /> 
       </DataTemplate> 
      </ComboBox.ItemTemplate> 
     </ComboBox> 
    </StackPanel> 

</Window> 

後面的代碼:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Data; 
using System.Windows.Media; 

namespace SelItemTest 
{ 
    public partial class Window1 : Window, INotifyPropertyChanged 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      Colors = new List<string>(); 
      Colors.Add(Brushes.Red.ToString()); 
      Colors.Add(Brushes.Blue.ToString()); 
      Colors.Add(Brushes.Yellow.ToString()); 

      Color = Brushes.Yellow; 

      DataContext = this; 
     } 

     public List<string> Colors { get; set;} 

     private SolidColorBrush _color; 
     public SolidColorBrush Color 
     { 
      get { return _color; } 
      set 
      { 
       _color = value; 
       if (PropertyChanged != null) 
       { 
        PropertyChanged(this, new PropertyChangedEventArgs("Color")); 
       } 
      } 
     } 

     #region INotifyPropertyChanged Members 
     public event PropertyChangedEventHandler PropertyChanged; 
     #endregion 
    } 

    public class StringToBrushConverter : IValueConverter 
    { 
     #region IValueConverter Members 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return value.ToString(); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      Color color = (Color)ColorConverter.ConvertFromString(value.ToString()); 
      SolidColorBrush scb = new SolidColorBrush(color); 
      return scb; 
     } 
     #endregion 
    } 
}