以编程方式更改 WPF 可编辑 ComboBox 的背景颜色

3
我正在尝试在运行时使用代码动态更改可编辑的ComboBox的背景颜色。特别地,我想要改变ComboBox中的可编辑TextBox的背景。虽然在SO上有几个关于此问题的答案,比如这个:WPF change the background color of an edittable combobox in code,但是它们都基于XAML和编辑默认模板。我不想那样做,我正在寻找一种通用的仅使用代码即可解决的方法。是否可能?我尝试了似乎很明显的解决方案:
TextBox textBox = (TextBox)comboBox.Template.FindName("PART_EditableTextBox", comboBox);
textBox.Background = Brushes.Yellow;

但这完全没有任何作用。我错过了什么吗?

您想更改单个ComboBox还是所有可编辑的ComboBox? - wimh
尝试一下:http://www.codeproject.com/Tips/84637/TIP-Change-background-of-WPF-Combobox - Roman
@Wimmel:一个。 - Master_T
@ChristophKn:如果您仔细阅读我的问题,您就会明白为什么那不是情况。正如我所指出的那样,该答案基于编辑ComboBox默认的XAML模板(顺便说一下,VS 2015甚至不允许我这样做)。我正在寻找一种直接在代码中编辑单个ComboBox背景的方法。 - Master_T
@Roma:这会改变下拉菜单的颜色,但不会改变用户可以输入文本的可编辑文本框的颜色。 - Master_T
设置 ComboBox.Background 应该仅更改可编辑文本框的背景。 - Bolu
2个回答

3
这是你可以做到的方法。
<ComboBox Loaded="MyCombo_OnLoaded"  x:Name="myCombo" IsEditable="True"></ComboBox>

private void MyCombo_OnLoaded(object sender, RoutedEventArgs e)
{
      var textbox = (TextBox)myCombo.Template.FindName("PART_EditableTextBox", myCombo);
      if (textbox!= null)
      {
           var parent = (Border)textbox.Parent;
           parent.Background = Brushes.Yellow;
       }
}

运行得非常好,而且也非常简单。 - Master_T
确实是好东西!我无法使用普通验证,但使用此功能和视图模型上的颜色属性实现了自定义验证。 - Master Azazel
哇,真的吗?这就是改变背景颜色所需的全部步骤?这已经足够让我不再考虑使用WPF而选择WinForms了。问题:我们应该如何找到必要的信息来自己解决类似“PART_EditableTextBox”这样的问题呢,而不是每次都向您询问我们想要更改的详细信息?我需要能够使用参考资料来查找信息,而不是阅读XAML或使用任何涉及XAML的工具。我不使用Visual Studio或Blend,也不使用XAML。 - RichardB

2

针对 XAML 爱好者的可重用 AttachedProperty 解决方案:

<ComboBox Background="Orange" IsEditable="True" Text="hi" local:ComboBoxHelper.EditBackground="Red"></ComboBox>

实现:

public static class ComboBoxHelper
{
    public static readonly DependencyProperty EditBackgroundProperty = DependencyProperty.RegisterAttached(
        "EditBackground", typeof (Brush), typeof (ComboBoxHelper), new PropertyMetadata(default(Brush), EditBackgroundChanged));

    private static void EditBackgroundChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
    {
        var combo = dependencyObject as ComboBox;
        if (combo != null)
        {
            if (!combo.IsLoaded)
            {
                RoutedEventHandler comboOnLoaded = null;
                comboOnLoaded = delegate(object sender, RoutedEventArgs eventArgs)
                {
                    EditBackgroundChanged(dependencyObject, args);
                    combo.Loaded -= comboOnLoaded;
                };
                combo.Loaded += comboOnLoaded;

                return;
            }

            var part = combo.Template.FindName("PART_EditableTextBox", combo);
            var tb = part as TextBox;
            if (tb != null)
            {
                var parent = tb.Parent as Border;
                if (parent != null)
                {
                    parent.Background = (Brush)args.NewValue;
                }
            }
        }
    }

    [AttachedPropertyBrowsableForType(typeof(ComboBox))]
    public static void SetEditBackground(DependencyObject element, Brush value)
    {
        element.SetValue(EditBackgroundProperty, value);
    }

    [AttachedPropertyBrowsableForType(typeof(ComboBox))]
    public static Brush GetEditBackground(DependencyObject element)
    {
        return (Brush) element.GetValue(EditBackgroundProperty);
    }
}

@Master_T 谢谢。这个实现的优点是它可以应用于默认样式,而不需要在每个组合框上瞎弄。附加属性是WPF中一些非常有用的功能之一。 - Dbl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接