Как прочитать переданный параметр в WPF UserControl?

Я создал пользовательский элемент управления в WPF:

<UserControl x:Class="TestUserControl.Controls.GetLatest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <TextBlock Name="theTextBlock"/>
</UserControl>

код позади имеет параметр под названием "FirstMessage", который он устанавливает в качестве текста моего TextBlock пользовательского элемента управления:

public partial class GetLatest : UserControl
{
    public string FirstMessage { get; set; }

    public GetLatest()
    {
        InitializeComponent();
        theTextBlock.Text = this.FirstMessage;
    }
}

в моем основном коде я могу установить параметр FirstMessage в моем пользовательском элементе управления с помощью intellisense:

<Window x:Class="TestUserControl.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    xmlns:controls="clr-namespace:TestUserControl.Controls"
    >
    <StackPanel>
        <controls:GetLatest FirstMessage="This is the title"/>
    </StackPanel>
</Window>

однако он по-прежнему не устанавливает текст. Я пробовал Text= "{Binding Path=FirstMessage} " и другие синтаксисы, которые я нашел, но ничего не работает.

как я могу получить доступ значение FirstMessage в моем пользовательском элементе управления?

5 ответов


ваш подход к привязке не работает, потому что ваше свойство FirstMessage не уведомляет, когда оно обновляется. Для этого используйте свойства зависимостей. См. ниже:

public partial class GetLatest : UserControl
{
    public static readonly DependencyProperty FirstMessageProperty = DependencyProperty.Register("FirstMessage", typeof(string), typeof(GetLatest));

    public string FirstMessage
    {
        get { return (string)GetValue(FirstMessageProperty); }
        set { SetValue(FirstMessageProperty, value); }
    }

    public GetLatest()
    {
        InitializeComponent();
        this.DataContext = this;
    }

}

XAML:

<UserControl x:Class="TestUserControl.Controls.GetLatest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TextBlock Text="{Binding FirstMessage}" />
</UserControl>

всякий раз, когда изменяется свойство FirstMessage, ваш текстовый блок будет обновляться.


FirstMessage устанавливается после вызова конструктора. Вы должны изменить свой текст из сеттера FirstMessage.

при инициализации объекта из XAML сначала вызывается конструктор по умолчанию, затем устанавливаются свойства объекта.


в этом быстром примере не будет использоваться привязка, потому что значение не настраивается до тех пор, пока не будет вызван конструктор по умолчанию, но вот как вы можете получить текст для отображения.

<UserControl x:Class="TestUserControl.Controls.GetLatest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="GetLatest_Loaded">
        <TextBlock Name="theTextBlock"/>
</UserControl>

затем просто измените файл cs следующим образом:

public partial class GetLatest : UserControl
{
    public string FirstMessage { get; set; }

    public GetLatest()
    {
        InitializeComponent();
        theTextBlock.Text = this.FirstMessage;
    }

    private void GetLatest_Loaded(object sender, RoutedEventArgs e)
    {
        theTextBlock.Text = this.FirstMessage;
    }
}

вместо этого я рекомендую работать над настройкой привязки, так как это довольно спагетти-подобный код.


вы также можете использовать:

public partial class GetLatest : UserControl
{
    private string _firstMessage;
    public string FirstMessage 
    {
        get { return _firstMessage; }
        set { _firstMessage = value; theTextBlock.Text = value; }
    }

    public GetLatest()
    {
        InitializeComponent();
    }
}

в случае кода, который вы разместили выше, это проблема синхронизации; свойство FirstMessage не имеет своего значения, назначенного при выполнении конструктора. Вам придется выполнить этот код в случае, происходящем позже, например, Loaded.