在Silverlight中扩展控件(ComboBox)

时间:2011-11-16 21:37:31

标签: silverlight combobox dependency-properties

我有一个简单的问题。我正在尝试将依赖项属性添加到组合框。我希望能够在最初显示时在组合框的表面上显示一个值。在ComboBox中有一个带有TextBlock的ContentPresenter。当用户选择ComboBox中的项目时,将设置TextBlock。如何使用默认值(不是其中一个项目)设置?显示“选择一个”之类的内容。

我可以使用'DefaultDisplay'依赖属性扩展ComboBox但是如何将该属性“链接”到属于控件模板的TextBlock?

感谢您提供任何帮助。

专利

1 个答案:

答案 0 :(得分:0)

我建议使用行为来代替依赖属性。实际上我已经为这个问题编写了其中一个。尝试将其添加到组合框并在行为上设置PromptText属性:

public class ComboBoxPromptBehavior : Behavior<ComboBox>
{
    [Category("Display")]
    public string PromptText
    {
        get { return (string)GetValue(PromptTextProperty); }
        set { SetValue(PromptTextProperty, value); }
    }

    public static readonly DependencyProperty PromptTextProperty = DependencyProperty.Register("PromptText", typeof(string), typeof(ComboBoxPromptBehavior), new PropertyMetadata(" "));

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
        AssociatedObject.LayoutUpdated += new EventHandler(AssociatedObject_LayoutUpdated);
    }

    void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
    {
        SetPromptText();
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.Loaded -= new RoutedEventHandler(AssociatedObject_Loaded);
        AssociatedObject.LayoutUpdated -= new EventHandler(AssociatedObject_LayoutUpdated);
    }

    void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        SetPromptText();
    }

    private void SetPromptText()
    {
        var textbox = AssociatedObject.FindChild<TextBlock>();
        if (textbox != null && string.IsNullOrWhiteSpace(textbox.Text))
        {
            textbox.Text = PromptText;
        }
    }
}

FindChild的扩展方法是:

public static T FindChild<T>(this DependencyObject element) where T : DependencyObject
{
    var childCount = VisualTreeHelper.GetChildrenCount(element);

    for (int i = 0; i < childCount; i++)
    {
        var child = VisualTreeHelper.GetChild(element, i);
        if (child is T)
        {
            return (T)child;
        }
        var match = child.FindChild<T>();
        if (match != null) return match;
    }

    return null;
}