WPF Bind Textbox in main windows from user controls

WPF Bind Textbox in main windows from user controls

我是 WPF 新手,正在尝试从用户控件绑定位于 mainwindow 中的文本框。

<Window x:Class="Databinding.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="360" Width="490">
<Grid HorizontalAlignment="Left" Width="480">
    <TextBox x:Name="EventTitle" HorizontalAlignment="Left" Height="23" Margin="40,19,0,0" TextWrapping="Wrap" Text="{Binding Path=FirstName}"   VerticalAlignment="Top" Width="120"/>
    <Button Content="Button" HorizontalAlignment="Left" Margin="195,20,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
    <StackPanel x:Name="Stck_Main" HorizontalAlignment="Left" Height="230" Margin="22,75,0,0" VerticalAlignment="Top" Width="439"/>
    <Button Content="UC" HorizontalAlignment="Left" Margin="371,20,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>

</Grid>

我还创建了一个 class 来管理值更新

class UIcontrol : INotifyPropertyChanged

{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _firstName;

    protected void Notify(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (value != _firstName)
            {
                _firstName = value;
                Notify("FirstName");
            }
        }
    }


}

我的问题:在主要 window 中,我使用了一个简单的用户控件。我想绑定此用户控件中的文本框值。 绑定通过 mainwindow 中的按钮操作,但用户控件没有任何反应。我想是数据上下文出了什么问题,但你能帮我找到正确的方法吗?

主要代码window

 public partial class MainWindow : Window
{
    private UIcontrol viewModel;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        viewModel = new UIcontrol();
        DataContext = viewModel;
        viewModel.FirstName = "Mike";
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        UC1 myUC = new UC1();
        Stck_Main.Children.Clear();
        Stck_Main.Children.Add(myUC);
    }

}

后面的用户控制代码是

public partial class UC1 : UserControl
{

    private UIcontrol viewModel;

    public UC1()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        viewModel = new UIcontrol();
        DataContext = viewModel;
        viewModel.FirstName = "Doe";
    }


}

然后是 XAML:

UserControl x:Class="Databinding.UC1"
         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" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="0,0,10,43">
    <Canvas Height="194" Margin="25,30,71,0" VerticalAlignment="Top" Background="White">
        <Button Content="Button" Canvas.Left="100" Canvas.Top="81" Width="75" Click="Button_Click" />
    </Canvas>
</Grid>

可能还有许多其他解决方案,但正如我在评论中所说,以下解决方案会起作用,并且会让您对问题有所了解。

只更新后面的UC1代码

public partial class UC1 : UserControl
{
    public UC1()
    {
        InitializeComponent();
    }

    private UIcontrol viewModel;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var window = FindParent<Window>(this);

        if(window != null)
        {
            var vm = window.DataContext as UIcontrol;
            if(vm != null)
            {
                vm.FirstName = "Doe";
            }
            else
            {
                viewModel = new UIcontrol();
                window.DataContext = viewModel;
                viewModel.FirstName = "Doe";
            }
        }
    }

    public static T FindParent<T>(DependencyObject child) where T : DependencyObject
    {
        //get parent item
        DependencyObject parentObject = VisualTreeHelper.GetParent(child);

        //we've reached the end of the tree
        if (parentObject == null) return null;

        //check if the parent matches the type we're looking for
        T parent = parentObject as T;
        if (parent != null)
            return parent;
        else
            return FindParent<T>(parentObject);
    }
}

作为旁注,请对 ViewModel 名称使用正确的符号 UIcontrol ViewModel 有点令人困惑..:)