【问题标题】:Setting ComboBox.SelectedItem in XAML based on matching object基于匹配对象在 XAML 中设置 ComboBox.SelectedItem
【发布时间】:2011-02-08 09:06:49
【问题描述】:

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

我还有一些保存当前颜色的十六进制值的数据和一个将十六进制转换为SolidColorBrush的转换器。

我正在尝试根据我的数据源中的颜色设置ComboBoxSelectedItem 属性。由于我的组合中填充了 SolidColourBrush 类型的对象,并且我的绑定转换器返回了 SolidColorBrush,因此我认为这很简单:

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

但是......它不起作用:(

我已经通过对ComboBox 的Background 属性使用完全相同的值来测试绑定是否在幕后工作。

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

这样做的正确方法是什么?当然,在仅 XAML 的样式中使用绑定是可能的,而且我不必做一些讨厌的 C# 迭代组合框中的所有项目来尝试找到匹配项(这看起来非常老派)......?

【问题讨论】:

  • 建议覆盖SolidColorBrush Equals 函数。默认情况下,Equals,比较两个项目时检查引用是否相同。您可以更改此行为并设置Equals 以检查例如颜色代码是否相同。检查this answer 以供参考。

标签: wpf data-binding combobox selecteditem


【解决方案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
    }
}

【讨论】:

    【解决方案2】:

    如果您使用的是 MVVM 模式,则将属性 SelectedHexColor 添加到您的视图模型并让视图模型在您的列表中搜索正确的纯色画笔,从中填充颜色画笔组合框并更新 @987654322 @组合框的选定项绑定到的视图模型的属性。

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

    最好的问候,
    奥利弗·哈纳皮

    【讨论】:

    • 嗯...好的。但我想我正在寻找一个更普遍的答案。如果我有一个包含 Foo 类型项目列表的组合框,并且我还有另一个 Foo 实例保存在其他地方(比方说,在 myFoo 中),那么肯定有一个 XAML-only 方式来说,“组合框的选定项目是 myFoo”,或者更准确地说,“组合框的选定项是与 myFoo 匹配的 Foo”……对吗?
    • 在这种情况下,您将需要实现值相等逻辑。为此,您可以将SolidColorBrush 包装在实现值相等(覆盖GetHashCode 和Equals)的对象中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    相关资源
    最近更新 更多