C# 管理和绑定用户控件
我是WPF的新手,现在遇到了一个场景,我找不到任何有效的解决方案。 在我的项目中,我有许多视图模型和用户控件。主窗口分为两部分,在左侧,我根据当前的viewmodel显示usercontrols,一切正常。当我想根据用户在左侧选择的内容在右侧显示第二个usercontrol时,问题就开始了。用户控件有许多文本框和组合框。如何从COSEQUITIVE视图模型绑定此数据C# 管理和绑定用户控件,c#,wpf,mvvm,user-controls,C#,Wpf,Mvvm,User Controls,我是WPF的新手,现在遇到了一个场景,我找不到任何有效的解决方案。 在我的项目中,我有许多视图模型和用户控件。主窗口分为两部分,在左侧,我根据当前的viewmodel显示usercontrols,一切正常。当我想根据用户在左侧选择的内容在右侧显示第二个usercontrol时,问题就开始了。用户控件有许多文本框和组合框。如何从COSEQUITIVE视图模型绑定此数据 //mainwindow.xaml <Window.resources> <Datatemplate Datat
//mainwindow.xaml
<Window.resources>
<Datatemplate Datatype={x:Type vm:Viewmodel1}>
<loc:Usercontrol1/> // in the left hand side
</DataTemplate>
<Datatemplate Datatype={x:Type vm:Viewmodel2}>
<loc:Usercontrol2/> // in the lefthand side
</DataTemplate>
</Window.Resources>
...
<Grid Grid.Column="0">
<ContentControl Content={Binding CurrentViewModel}/>
</Grid>
<Grid Grid.Column="1">
<Grid.Resources>
<Datatemplate Datatype={x:Type vm:Viewmodel1}>
<loc:Usercontrol3 NameDp={Binding Name}/> // in the right hand side
</DataTemplate>
<Datatemplate Datatype={x:Type vm:Viewmodel2}>
<loc:Usercontrol3/> // in the rightthand side
</DataTemplate>
</Grid.Resources>
</Grid>
// Usercontrol3.xaml
<Grid>
<TextBox Text="{Binding Path=NameDp, ElementName=UserControl3}" />
</Grid>
// UserControl3.cs
public static readonly DependencyProperty NameUCProperty =DependencyProperty.Register("NameDp", typeof(string), typeof(UserControl3), new FrameworkPropertyMetadata(NamePropertyChanged));
public string NameDp
{
get
{
return (string)GetValue(NameUCProperty);
}
set
{
SetValue(NameUCProperty, value);
}
}
//ViewModel
Public Name {get;set;}
//mainwindow.xaml
//在左手边
//在左手边
...
//在右手边
//在右边
//Usercontrol3.xaml
//UserControl3.cs
public static readonly dependencProperty NameUCProperty=dependencProperty.Register(“NameDp”、typeof(string)、typeof(UserControl3)、new FrameworkPropertyMetadata(NamePropertyChanged));
公共字符串名称DP
{
得到
{
返回(字符串)GetValue(NameUCProperty);
}
设置
{
SetValue(NameUCProperty,value);
}
}
//视图模型
公共名称{get;set;}
在每个viewmodels中,我从数据库中获取数据,并希望根据用户选择将这些数据绑定到右侧的UserControl。如何绑定这些数据?
这是正确的方法还是我完全错了?这绝对是一种方法。对我来说,我会这样组织事情。我这里有一个原型,演示了这个东西是如何工作的 首先,我们的主窗口
<Window x:Class="WpfUserControlsBindingListeningNotMuchHere.MainWindow"
xmlns:t="clr-namespace:WpfUserControlsBindingListeningNotMuchHere"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:ms="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<t:ViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<t:UserControl1 x:Name="uc1"
Items="{Binding Items}"
Selected="{Binding Selected, Mode=TwoWay}" />
<t:UserControl2 Grid.Column="1"
DataContext="{Binding Result}" />
</Grid>
</Window>
因此,我只是在观察对Selected的更改,在这一点上我进行工作(业务逻辑)并在另一个属性中公开结果。然后将其绑定到UI中的第二个UserControl
正如我所说,UC代码是微不足道的
<UserControl x:Class="WpfUserControlsBindingListeningNotMuchHere.UserControl1"
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"
x:Name="root">
<ListBox ItemsSource="{Binding Items, ElementName=root}"
SelectedItem="{Binding Selected, ElementName=root}" />
</UserControl>
在暗藏中(天哪,暗藏中小心邪恶)
公共部分类UserControl1:UserControl
{
#区域项目
公共静态只读从属属性ItemsProperty=
从属属性。寄存器(
“项目”,
类型(IEnumerable),
类型(用户控制1),
新的UIPropertyMetadata(空);
公共数字项目
{
get{return(IEnumerable)GetValue(ItemsProperty);}
set{SetValue(ItemsProperty,value);}
}
#端区
#选定区域
公共静态只读从属属性SelectedProperty=
从属属性。寄存器(
“选定”,
类型(对象),
类型(用户控制1),
新的UIPropertyMetadata(空);
选定的公共对象
{
获取{return(object)GetValue(SelectedProperty);}
set{SetValue(SelectedProperty,value);}
}
#端区
公共用户控制1()
{
初始化组件();
}
}
及
此模板上没有代码隐藏。您只需定义一次数据模板,而不是多次。从绑定源开始,在逻辑树上执行搜索,以查找与绑定对象的数据类型匹配的第一个数据模板。除此之外,这看起来是正确的。它不工作吗?@Will正如我提到的,我想先加载左手侧,然后当用户选择我想打开右手侧的下一个usercontrol时加载。若我把它们放在一起,我将如何指示哪一个应该首先显示,哪一个是正确的。@左手边会工作得很好吗。这样,我甚至可以加载右侧的用户控件。真正的问题是我无法绑定的第二组用户控件。文本框始终为空。我不太明白,这要看情况而定。“当用户选择某物时”意味着什么?例如,如果UC1显示项目列表,并且您希望UC2显示选定的项目。。。那很容易。在UC1中,将列表的SelectedItem属性绑定到UserControl上的公共DependencyProperty(是,codebehind)。然后,在窗口中,将第二个ContentControl绑定到该公共DependencyProperty。@Will Yes左侧始终是列表,当用户从列表中选择项目时。项目的详细信息应显示在UC2中。现在,当用户双击时,我在viewmodel中实现了一个命令,并将所选项目作为命令参数发送到数据库中进行搜索,以获取更多详细信息。一旦我有了它,我想从那里直接绑定到Usercontrol。如果可能的话。我不知道该怎么做。小的psuedo代码会很有帮助。我会尝试一下,如果你能把usercontrol代码也放进去,那就太好了。我试了一整天,但按照我的要求,它不起作用。列表始终是绑定的,但第二个集合不绑定。我的第二组usercontrol不仅仅是一个文本框,它就像一个有许多标签和组合框的表单etc@user1767798:请注意第二个用户控件。“选定”项绑定到此控件的DataContext。在此用户控件中,各个表单控件应绑定到此对象的属性。这就像绑定到窗口中ViewModel的属性一样。不确定您为什么会遇到问题,因为这很琐碎…@感谢您的时间和建议,我可以看到我的viewmodel属性正在获取数据,但它并不令人不快。但无论如何,我通过删除usercontrol并将它们放入资源字典中并根据当前视图模型显示,解决了这个问题。它工作得很好。
<UserControl x:Class="WpfUserControlsBindingListeningNotMuchHere.UserControl1"
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"
x:Name="root">
<ListBox ItemsSource="{Binding Items, ElementName=root}"
SelectedItem="{Binding Selected, ElementName=root}" />
</UserControl>
public partial class UserControl1 : UserControl
{
#region Items
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(
"Items",
typeof(IEnumerable<object>),
typeof(UserControl1),
new UIPropertyMetadata(null));
public IEnumerable<object> Items
{
get { return (IEnumerable<object>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
#endregion
#region Selected
public static readonly DependencyProperty SelectedProperty =
DependencyProperty.Register(
"Selected",
typeof(object),
typeof(UserControl1),
new UIPropertyMetadata(null));
public object Selected
{
get { return (object)GetValue(SelectedProperty); }
set { SetValue(SelectedProperty, value); }
}
#endregion
public UserControl1()
{
InitializeComponent();
}
}
<UserControl x:Class="WpfUserControlsBindingListeningNotMuchHere.UserControl2"
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">
<TextBlock Text="{Binding}" />
</UserControl>