简体   繁体   English

使用用户控件时的WPF数据绑定

[英]WPF DataBinding when using usercontrols

i'm new to WPF and the MVVM pattern, i'm trying to make an app that uses several controls so i create each control separately and i am facing some difficulty for how to share data between controls 我是WPF和MVVM模式的新手,我试图制作一个使用多个控件的应用程序,因此我分别创建了每个控件,并且在如何在控件之间共享数据时遇到了一些困难

lets say i have a control that has a label and another control that contains a textbox, in the main window i want when i add the two custom controls i need the label control to show what i'm typing in the text box, i know how to implement that if i use the label and textbox directly in my window but i need that to solve similar issue, here is the Label Control 可以说我有一个带有标签的控件和另一个包含文本框的控件,在主窗口中,当我添加两个自定义控件时,我需要标签控件来显示我在文本框中键入的内容,我知道如果我直接在窗口中使用标签和文本框,但要解决类似问题,该如何实现,这是标签控件

<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>

TextBox Custom control TextBox自定义控件

<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>

and this is the window code 这是窗口代码

<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>

With binding, controls will inherit the datacontext of their parent. 通过绑定,控件将继承其父级的数据上下文。

If you set the window datacontext to "Model" (or the controls datacontext to "Model" if you need to keep it restrained) and that model has a property called "SomeText", you could bind the textbox and label as shown below: 如果将窗口数据上下文设置为“模型”(或者如果需要保持约束,则将控件数据上下文设置为“模型”)并且该模型具有名为“ SomeText”的属性,则可以如下所示绑定文本框和标签:

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

If you need further info, please let me know. 如果您需要更多信息,请告诉我。 Bindings are a beast to start with. 绑定是一开始的野兽。

You shouldn't need any code behind to wire up the controls. 您不需要背后的任何代码即可连接控件。

Just knocked up an example that might be of use. 只是敲了一个可能有用的例子。 Remember to use the output window to identify binding errors if needed. 请记住,如果需要,请使用输出窗口来识别绑定错误。

In this example, my window is bound to a viewmodel, which has a property called 'Model'. 在此示例中,我的窗口绑定到一个视图模型,该模型具有一个名为“模型”的属性。 The model has a Forename and surname property. 该模型具有一个“姓氏”和“姓氏”属性。

We have a label in the main window and a textbox in a control. 我们在主窗口中有一个标签,在控件中有一个文本框。 Between this answer and my first, I'll let you finish it off to get it how you want. 在这个答案和我的第一个答案之间,我将让您完成它,以达到所需的目的。

Main Window Code (in this case the datacontext has been quickly set in code behind, though there are many ways to do it). 主窗口代码(在这种情况下,数据上下文已在后面的代码中快速设置,尽管有很多方法可以做到)。

Code Behind 背后的代码

  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 窗口

<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>

User Control Code. 用户控制代码。

<UserControl x:Class="WPFTutSimple.UserControls.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">
  <StackPanel>
    <TextBox Text="{Binding Path=Model.Surname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
             Width="200" BorderBrush="Black" HorizontalAlignment="Left"></TextBox>

  </StackPanel>
</UserControl>

If you want/need to see what is going on in your usercontrols (and you are using WPF proper, not WinRT) you can tap into the DataContextChanged Event in the user control and check the 'e' values as the datacontext changes: 如果您希望/需要查看用户控件中发生了什么(并且使用的是WPF,而不是WinRT),则可以点击用户控件中的DataContextChanged事件,并在数据上下文更改时检查“ e”值:

  public partial class TextBoxControl : UserControl
  {
    public TextBoxControl()
    {
      InitializeComponent();
      this.DataContextChanged += TextBoxControl_DataContextChanged;
    }

    void TextBoxControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
      //Set breakpoint here...
    }
  }

you can use dependency properties to fit your usercontrols. 您可以使用依赖项属性来适合您的用户控件。

<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>

codebehind add the dependency property 代码隐藏添加依赖项属性

   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); }
    }

now you can use this control in any view like this: 现在您可以在任何这样的视图中使用此控件:

 <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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM