使用usercontrol时的WPF DataBinding

时间:2014-01-21 14:00:09

标签: c# wpf mvvm

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

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

<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自定义控件

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

3 个答案:

答案 0 :(得分:2)

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

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

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

如果您需要进一步的信息,请告诉我。绑定是一个开始的野兽。

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

答案 1 :(得分:0)

刚刚敲了一个可能有用的例子。如果需要,请记住使用输出窗口来识别绑定错误。

在这个例子中,我的窗口绑定到一个viewmodel,它有一个名为'Model'的属性。该模型具有Forename和surname属性。

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

主窗口代码(在这种情况下,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="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>

如果您希望/需要查看用户控件中发生了什么(并且您正在使用WPF,而不是WinRT),您可以使用用户控件中的DataContextChanged事件并在datacontext更改时检查“e”值:

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

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

答案 2 :(得分:0)

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

<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添加依赖项属性

   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>