Расширение элемента управления (ComboBox) в Silverlight - PullRequest
0 голосов
/ 17 ноября 2011

У меня простая проблема. Я пытаюсь добавить свойство зависимости в поле со списком. Я хочу иметь возможность отображать значение на лицевой панели поля со списком, когда оно отображается изначально. Внутри ComboBox есть ContentPresenter с TextBlock. Этот TextBlock устанавливается, когда пользователь выбирает элемент в ComboBox. Как я могу установить это со значением по умолчанию (не один из пунктов)? Покажите что-то вроде «выберите один».

Я могу расширить ComboBox с помощью свойства зависимостей DefaultDisplay, но как мне связать это свойство с TextBlock, который является частью шаблона элемента управления?

Спасибо за любую помощь в этом.

Pat

1 Ответ

0 голосов
/ 17 ноября 2011

Вместо свойства зависимости я бы предложил использовать для этого поведение. У меня на самом деле уже было одно из этих написано для этой проблемы. Попробуйте, добавив его в свой выпадающий список и задав свойство 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;
}
...