WPF4: как установить значение в UserControl из главного окна? - PullRequest
0 голосов
/ 30 августа 2010

Это должно быть просто, по крайней мере, это было в старом добром .Net, где потребовалось, может быть, четыре строки кода. Я работаю в VS2010, C #, WPF4.

У меня есть пользовательский элемент управления с текстовым полем. Когда я нажимаю кнопку в главном окне, я хочу, чтобы текстовое поле моего пользовательского элемента управления отображало некоторый текст. Возможно ли это в WPF4 с менее чем 500 строками эзотерического кода?

Проблема в том, что, хотя я знаю, что текстовое поле получает новый текст, о чем свидетельствуют точки останова в коде пользовательского элемента управления, этот текст никогда не отражается в главном окне. Главное окно по-прежнему показывает оригинальный текст. Это должно быть какой-то обязательной вещью, и я действительно не думаю, что мне нужно было бы создавать шаблоны и ресурсы и все для этой простой ситуации. Это должно быть что-то простое, что я забыл в лесу WPF4. Ниже то, что у меня есть. После нажатия кнопки текстовое поле остается пустым; это не говорит "привет земляне".

В коде управления пользователя:

public partial class UserControl1 : UserControl
{
    public static readonly DependencyProperty TextProperty;

    public UserControl1()
    {
        InitializeComponent();
    }

    static UserControl1()
    {
        TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new UIPropertyMetadata(null));
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

}

Пользовательский контроль xaml:

<UserControl x:Class="WTFUserControlLibrary.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid Height="164" Width="220">
    <TextBox Name="txtTest" BorderBrush="red" BorderThickness="2" Height="25" Text="{Binding ElementName=UserControl1, Path=Text, Mode=TwoWay}"></TextBox>
</Grid>

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

Код главного окна:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        WTFUserControlLibrary.UserControl1 uc = new WTFUserControlLibrary.UserControl1();
        uc.Text = "hello earthlings";
    }
}

и главное окно xaml:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:my="clr-namespace:WTFUserControlLibrary;assembly=WTFUserControlLibrary"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="71,65,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    <my:UserControl1 HorizontalAlignment="Left" Margin="71,94,0,0" Name="userControl11" VerticalAlignment="Top" Height="116" Width="244" />
</Grid>

Спасибо землянам (а также тем, кто создал этот беспорядок!)

1 Ответ

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

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

Вместо этого дайте вашему usercontrol имя в XAML:

x:Name="uc"

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

обновление

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

<UserControl x:Class="WTFUserControlLibrary.UserControl1"
         x:Name="thisControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid Height="164" Width="220">
    <TextBox Name="txtTest" BorderBrush="red" 
             BorderThickness="2" Height="25" 
             Text="{Binding ElementName=thisControl, Path=Text, Mode=TwoWay}" />
</Grid>

Я добавил x:Name="thisControl" к корневому элементу UserControl, а затем сослался на это в привязке.

Я попробую объяснить привязку:

У вас есть это текстовое поле внутри вашего пользовательского элемента управления, но вы хотите иметь возможность привязать текстовое значение к чему-то вне пользовательского элемента управления. То, что вы сделали, - это установили свойство зависимости для пользовательского элемента управления и привязали это текстовое поле к нему, чтобы вы использовали передаваемые значения инфраструктуры привязки с верхнего уровня UserControl для составляющих элементов управления внутри него.

В основном это выглядит так:

data
    ---> bind UserControl1.Text to data
         ---> bind TextBox.Text to UserControl1.Text
...