基于匹配对象在XAML中设置ComboBox.SelectedItem

时间:2010-04-15 13:01:09

标签: wpf data-binding combobox selecteditem

我有模板ComboBox,它基本上是一个简单的调色板。它填充了SolidColorBrush个对象的列表。

我还有一些数据包含当前颜色的十六进制值以及一个将十六进制转换为SolidColorBrush的转换器。

我想要的是根据我的DataSource中的颜色设置SelectedItem的{​​{1}}属性。由于我的组合填充了ComboBox类型的对象,并且我的绑定转换器返回SolidColourBrush,我认为它就像说:

SolidColorBrush

然而......它不起作用:(

我已经通过对SelectedItem="{Binding Color, Converter={StaticResource StringToBrush}}" 的Background属性使用完全相同的值来测试绑定是否在幕后工作。

所以,显然我不能只说SelectedItem = [something],其中[something]基本上是一个与我想要选择的项目相等的对象。

这样做的正确方法是什么?当然,在使用绑定的XAML-style风格中,我可以不必做一些令人讨厌的C#迭代组合框中的所有项目试图找到一个匹配(看起来非常古老的学校)......?

2 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:0)

我正在使用MVVM模式,然后将属性SelectedHexColor添加到视图模型中,让视图模型在列表中搜索正确的纯色画笔,从中填充颜色画笔组合框并更新视图模型的SelectedBrush属性,组合框的选定项目绑定到该属性。

[edit]我刚看到你想避免使用C#代码,因为你认为它是老派的。但这是MVVM模式的优势,因为您可以对这个已经是复杂业务逻辑的代码进行单元测试。把它放在XAML中是非常不安全的,因为你不能对它进行单元测试,因此你无法获得正确的功能(除了使用自动ui测试,这些测试比单元测试更复杂)。

最诚挚的问候,
Oliver Hanappi