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