Установка значения свойства XAML для пользовательского элемента управления - PullRequest
7 голосов
/ 06 июля 2010

У меня есть пользовательский элемент управления в WPF, который я хочу, чтобы текст одной из его меток читался из XAML, где он используется. Следовательно ..

Мой пользовательский контроль:

 <UserControl x:Class="muc">
        <Label Foreground="#FF7800" FontSize="20" FontWeight="Bold">          
             <Label.Content>
                <Binding ElementName="TestName" Path="." />
             </Label.Content>
        </Label>
 </UserControl>

Затем, используя его:

 <mycontorls:muc TestName="This is a test" />

Но это не работает ... Как я могу прочитать свойства?

Ответы [ 4 ]

8 голосов
/ 30 августа 2010

Я попробовал первые два ответа, и то, что я получил, сработало в коде, но не в XAML (также не позволяет видеть изменения в представлении дизайна при использовании элемента управления).

Чтобы получить свойство, работающее как любое другое встроенное, вот полный процесс: (В примере добавлено свойство зависимости типа Nullable для отображения в элементе управления в виде текста или по умолчанию, если значение равно NULL)

  1. В файле кода:

    1.a Определите свойство зависимости:

    public static readonly DependencyProperty MyNumberProperty = DependencyProperty.Register("MyNumber", typeof(Nullable<int>), typeof(MyUserControl), new PropertyMetadata(null, new PropertyChangedCallback(OnMyNumberChanged)));
    

    1.b Реализация обратного вызова OnMyNumberChanged:

    private static void OnMyNumberChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args){
        // When the color changes, set the icon color PlayButton
        MyUserControl muc = (MyUserControl)obj;
        Nullable<int> value = (Nullable<int>)args.NewValue;
        if (value != null)
        {
            muc.MyNumberTextBlock.Text = value.ToString();
        }
        else
        {
            muc.MyNumberTextBlock.Text = "N/A";
        }
    }
    

    1.c реализует свойство MyNumber (не зависимость) для использования свойства зависимости для простоты использования кода:

    public Nullable<int> MyNumber{
        get
        {
            return (Nullable<int>)GetValue(MyNumberProperty);
        }
        set
        {
            SetValue(MyNumberProperty, value);
            OnTargetPowerChanged(this, new DependencyPropertyChangedEventArgs(TargetPowerProperty, value, value));    // Old value irrelevant.
        }
    }
    
  2. В файле XAML свяжите текст элемента управления TextBlock со свойством (не зависимостью), чтобы получить значение по умолчанию для свойства зависимости, если оно не установлено пользователем элемента управления (при условии, что вы вызвали корневой элемент). пользовательского элемента управления "RootElement"):

Этот код:

 < TextBlock Name="MyNumberTextBlock" Text="{Binding MyNumber, ElementName=RootElement}"/>
4 голосов
/ 06 июля 2010

Если вы даете корневому элементу UserControl имя, то вы можете ссылаться на него, используя ElementName:

<UserControl x:Class="muc"
             Name="rootElement">
    <Label Foreground="#FF7800" FontSize="20" FontWeight="Bold">
        <Label.Content>
            <Binding ElementName="rootElement" Path="TestName" />
        </Label.Content>
    </Label>
</UserControl>

Вы также можете использовать синтаксис расширения разметки, чтобы сделать его немного короче:

<UserControl x:Class="muc"
             Name="rootElement">
    <Label Foreground="#FF7800" FontSize="20" FontWeight="Bold"
           Content="{Binding TestName, ElementName=rootElement}"/>
</UserControl>

Также помните, что ваш элемент управления будет создан до того, как будут установлены его свойства. Вам нужно будет либо реализовать INotifyPropertyChanged, либо иметь TestName свойство зависимости, чтобы привязка переоценивалась после установки свойства.

3 голосов
/ 06 июля 2010

Я сделал это только с Silverlight, но я не удивлюсь, если он будет работать точно так же!

// <summary>
// Xaml exposed TextExposedInXaml property.
// </summary>
public static readonly DependencyProperty TestNameProperty = DependencyProperty.Register("TestName", typeof(string), typeof(NameOfMyUserControl), new PropertyMetadata(string.empty));

// <summary>
 // Gets or sets the control's text
// </summary>
public string TextExposedInXaml
{
            get
            {
                return (string)GetValue(TestNameProperty );
            }

            set
            {
                SetValue(TestNameProperty , value);

                // set the value of the control's text here...!
            }
}
0 голосов
/ 06 июля 2010

{Binding ElementName=x} привязывается к элементу с именем x в дереве элементов, здесь нет ничего, что касалось бы свойства TestName.Если вам нужно свойство в вашем пользовательском элементе управления, вам нужно определить свойство в классе, соответствующем этому пользовательскому элементу управления (в вашем случае это будет muc), и использовать {Binding RelativeSource={RelativeSource FindAncestor, ...}} для ссылки на него в вашем пользовательском элементе управления (см. здесь для подробной информации) или дайте ему имя, чтобы вы могли использовать ElementName.

...