C# 使用usercontrols时的WPF数据绑定

C# 使用usercontrols时的WPF数据绑定,c#,wpf,mvvm,C#,Wpf,Mvvm,我是WPF和MVVM模式的新手,我正在尝试制作一个使用多个控件的应用程序,因此我分别创建每个控件,并且我在如何在控件之间共享数据方面面临一些困难 假设我有一个有标签的控件和另一个包含文本框的控件, 在我想要的主窗口中,当我添加两个自定义控件时,我需要label控件来显示我在文本框中键入的内容,如果我直接在窗口中使用label和textbox,我知道如何实现,但我需要它来解决类似的问题, 这是标签控件 <UserControl x:Class="TestWPF2.Views.LabelCon

我是WPF和MVVM模式的新手,我正在尝试制作一个使用多个控件的应用程序,因此我分别创建每个控件,并且我在如何在控件之间共享数据方面面临一些困难

假设我有一个有标签的控件和另一个包含文本框的控件, 在我想要的主窗口中,当我添加两个自定义控件时,我需要label控件来显示我在文本框中键入的内容,如果我直接在窗口中使用label和textbox,我知道如何实现,但我需要它来解决类似的问题, 这是标签控件

<UserControl x:Class="TestWPF2.Views.LabelControl"
             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>
        <Label ></Label>
    </Grid>
</UserControl>

文本框自定义控件

<UserControl x:Class="TestWPF2.Views.TextBoxControl"
             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>
        <TextBox ></TextBox>
    </Grid>
</UserControl>

这是窗口代码

<Window x:Class="TestWPF2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:V="clr-namespace:TestWPF2.Views"
        xmlns:Controls="clr-namespace:TestWPF2.Views"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel LastChildFill="True">

        <Controls:TextBoxControl   ></Controls:TextBoxControl>
        <Controls:LabelControl   ></Controls:LabelControl>
    </DockPanel>
</Window>

通过绑定,控件将继承其父控件的datacontext

如果将窗口datacontext设置为“Model”(或者如果需要将控件datacontext设置为“Model”(如果需要将其约束),并且该模型具有名为“SomeText”的属性,则可以绑定文本框和标签,如下所示:

<TextBox BorderBrush="Black" Text="{Binding Path=Model.SomeText,UpdateSourceTrigger=PropertyChanged}" />

如果你需要更多的信息,请告诉我。绑定从一开始就是一个庞然大物


您不需要任何代码来连接控件。

刚刚创建了一个可能有用的示例。如果需要,记得使用输出窗口来识别绑定错误

在本例中,我的窗口绑定到一个viewmodel,它有一个名为“Model”的属性。该模型具有名和姓属性

我们在主窗口中有一个标签,在控件中有一个文本框。在这个答案和我的第一个答案之间,我会让你完成它,以得到你想要的

主窗口代码(在本例中,datacontext已在代码隐藏中快速设置,尽管有许多方法可以实现)

代码隐藏

  public partial class BindingTest : Window
  {
    public BindingTest()
    {
      InitializeComponent();

      Models.NamesModel nm = new Models.NamesModel();
      nm.Forename = "Bill";
      nm.Surname = "Gates";
      ViewModels.NamesViewModel vm = new ViewModels.NamesViewModel(nm);


      this.DataContext = vm;
    }
  }
窗口

<Window x:Class="WPFTutSimple.BindingTest"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ctrl="clr-namespace:WPFTutSimple.UserControls"
        Title="BindingTest" Height="300" Width="300"
        >
  <StackPanel>

    <Label Content="Name"></Label>
    <Label Content="{Binding Path=Model.Surname}"></Label>
    <ctrl:TextBoxControl />

  </StackPanel>
</Window>

您可以使用依赖项属性来适应您的用户控件

<UserControl x:Class="TestWPF2.Views.TextBoxControl"
         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"
         x:Name="uc">
<Grid>
    <TextBox Text="{Binding ElementName=uc, Path=MyText}"></TextBox>
</Grid>
</UserControl>
现在,您可以在以下任何视图中使用此控件:

 <Window x:Class="TestWPF2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:V="clr-namespace:TestWPF2.Views"
    xmlns:Controls="clr-namespace:TestWPF2.Views"
    Title="MainWindow" Height="350" Width="525">
   <DockPanel LastChildFill="True">

    <Controls:TextBoxControl MyText="{Binding Path=YourPropertyYouWannaBindTo}"  />
    <Controls:LabelControl   ></Controls:LabelControl>
</DockPanel>
 </Window>


作为旁白,您不应该创建
UserControl
仅仅是为了像
标签或
文本框那样包装单个控件;只需直接实例化
标签
文本框
。我不知道你的实际代码是否能做到这一点,或者这只是一个简化的示例。请看一看以正确的方式执行。你可能应该在问题中包含“代码隐藏”谢谢你的回答,我知道控件将继承其父控件的datacontext,除非您指定datacontext,但在我的示例中,我需要为每个自定义控件使用不同的viewModel,所以我的问题是这样做的最佳实践是什么,我可以使用singleton属性,如果我使用singletonI,则文本框和标签将绑定到同一属性。我不会使用singleton。如果我使用2个viewmodels,我会将它们都绑定到同一个(a的实例)模型上,这样更改就会在整个过程中大量增加。我们对BindableBase和CSLA做了类似的工作。虽然没有对PRISM做太多的工作,但是假设您可以以相同的方式使用所有MVVM框架。
<UserControl x:Class="TestWPF2.Views.TextBoxControl"
         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"
         x:Name="uc">
<Grid>
    <TextBox Text="{Binding ElementName=uc, Path=MyText}"></TextBox>
</Grid>
</UserControl>
   public static readonly DependencyProperty MyTextProperty =
     DependencyProperty.Register("MyText", typeof(string),
     typeof(TextBoxControl), new FrameworkPropertyMetadata(""));

    public stringMyText
    {
        get { return (bool)GetValue(MyTextProperty); }
        set { SetValue(MyTextProperty, value); }
    }
 <Window x:Class="TestWPF2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:V="clr-namespace:TestWPF2.Views"
    xmlns:Controls="clr-namespace:TestWPF2.Views"
    Title="MainWindow" Height="350" Width="525">
   <DockPanel LastChildFill="True">

    <Controls:TextBoxControl MyText="{Binding Path=YourPropertyYouWannaBindTo}"  />
    <Controls:LabelControl   ></Controls:LabelControl>
</DockPanel>
 </Window>