我是WPF的新手,我有一个问题关注将两个不同的ViewModel绑定到两个UserControls 这将附加到Tabcontrol中的两个Tabpages。
我的代码摘要如下:
MainWindow.xaml
<Window.Resources>
<local:UserControl1Model x:Key="Control1Model" />
<local:UserControl2Model x:Key="Control2Model" />
</Window.Resources>
<Grid HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="592">
<Grid HorizontalAlignment="Left" Height="45" Margin="0,330,-1,-45" VerticalAlignment="Top" Width="593">
<Button Content="Button" HorizontalAlignment="Left" Margin="490,5,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
<TabControl HorizontalAlignment="Left" Height="330" VerticalAlignment="Top" Width="592" >
<TabItem x:Name="UserControl1TabItem" Header="User Control 1" >
<Grid x:Name="UserControl1Tabpage" Background="#FFE5E5E5" Margin="0,0,-4,-2" Height="300" VerticalAlignment="Top" IsEnabled="true" >
<local:UserControl1 VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Control1Model}}" />
</Grid>
</TabItem>
<TabItem x:Name="UserControl2TabItem" Header="User Control 2">
<Grid x:Name="UserControl2Tabpage" Background="#FFE5E5E5">
<local:UserControl2 VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Control2Model}}" />
</Grid>
</TabItem>
</TabControl>
</Grid>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
private UserControl1Model _userControl1Model = new UserControl1Model();
private UserControl2Model _userControl2Model = new UserControl2Model();
public MainWindow()
{
InitializeComponent();
_userControl1Model.Message = "Hello";
_userControl2Model.Message = "Test";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Will do something
}
}
UserControl1Model.cs
public class UserControl1Model : INotifyPropertyChanged
{
private string _message;
public string Message
{
get { return _message; }
set
{
_message = value;
OnPropertyChanged("Message");
}
}
public UserControl1Model()
{
}
// Create the OnPropertyChanged method to raise the event
protected void OnPropertyChanged(string message)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(message));
}
}
#region INotifyPropertyChanged Members
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
为了尝试目的,UserControl2Model.cs的内容与UserControl1Model.cs相同
UserControl1.xaml
<UserControl.Resources>
<app:UserControl1Model x:Key="Control1Model" />
</UserControl.Resources>
<Grid Margin="0,0,0,42" DataContext="{Binding Source={StaticResource Control1Model}}">
<Label Content="Test:" HorizontalAlignment="Left" Margin="48,57,0,0" VerticalAlignment="Top" Width="47"/>
<TextBox x:Name="Conrol1ModelTextbox" HorizontalAlignment="Left" Height="23" Margin="90,59,0,0" TextWrapping="Wrap"
Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Top" Width="466" />
</Grid>
UserControl1.xaml.cs
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
}
UserControl2.xaml
<UserControl.Resources>
<app:UserControl2Model x:Key="Control2Model" />
</UserControl.Resources>
<Grid Margin="0,0,0,42" DataContext="{Binding Source={StaticResource Control2Model}}">
<Label Content="Test:" HorizontalAlignment="Left" Margin="48,57,0,0" VerticalAlignment="Top" Width="47"/>
<TextBox x:Name="Conrol2ModelTextbox" HorizontalAlignment="Left" Height="23" Margin="90,59,0,0" TextWrapping="Wrap"
Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Top" Width="466" />
</Grid>
为了尝试目的,UserControl2.xaml.cs的内容与UserControl1.xaml.cs相同
我的问题是两个用户控件的初始值,“Hello”和“Test”,它们在MainWindow.xaml.cs中初始化不能 被“绑定”到用户控件文本框中。我做错了什么或错过了什么?
答案 0 :(得分:2)
宣布此类资源时
<Window.Resources>
<local:UserControl1Model x:Key="Control1Model" />
<local:UserControl2Model x:Key="Control2Model" />
</Window.Resources>
您正在使用在MainWindow.cs中声明的实例构建UserControl1Model和UserControl2Model的新实例
此外,您不会为MainWindow创建任何ViewModel。你应该像这样创建一个MainWindowViewModel
public class MainWindowViewModel : INotifyPropertyChanged
{
public ViewModelLocator
{
this.FirstModel= new UserControl1Model
{
Message = "Hello";
}
this.SecondModel = new UserControl2Model
{
Message = "Test";
}
}
private UserControl1Model firstModel
public UserControl1Model FirstModel
{
get
{
return this.firstModel;
}
set
{
this.firstModel= value;
OnPropertyChanged("FirstModel");
}
}
// Same for the UserControl2Model
// implementation of the INotifyPropertyChanged
}
此外,您还需要为MainWindow设置DataContext。
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
从UserControl xamls中删除资源。您已经在MainWindow.xaml中定义了DataContext,但绑定应该从MainWindowViewModel绑定。
<local:UserControl1 VerticalAlignment="Top" DataContext="{Binding FirstModel}" />
答案 1 :(得分:1)
创建ViewModelLocator。你可以在互联网上找到这个主题的各种网站。
一个简单的例子是:
public class ViewModelLocator
{
public UserControl1Model UserControl1Model { get; set; } = new UserControl1Model();
public UserControl2Model UserControl2Model { get; set; } = new UserControl2Model();
public ViewModelLocator
{
UserControl1Model.Message = "Hello";
UserControl2Model.Message = "Test";
}
}
然后你可以在你的观点中使用它
<UserControl.Resources>
<app:ViewModelLocator x:Key="ViewModelLocator" />
</UserControl.Resources>
<Grid Margin="0,0,0,42" DataContext="{Binding UserControl2Model Source={StaticResource ViewModelLocator}}">
<Label Content="Test:" HorizontalAlignment="Left" Margin="48,57,0,0" VerticalAlignment="Top" Width="47"/>
<TextBox x:Name="Conrol2ModelTextbox" HorizontalAlignment="Left" Height="23" Margin="90,59,0,0" TextWrapping="Wrap"
Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Top" Width="466" />
</Grid>
答案 2 :(得分:1)
假设我在xaml中创建了这个实例,如下所示:
<Window.Resources> <local:MainWindowViewModel x:Key="MainWindowViewModel" /> </Window.Resources>
而不是在MainWindow.xaml.cs
内创建。然后,我如何在MainWindow.xaml.cs
内引用此实例,例如从MainWindowViewModel.ViewModelLocator.FirstModel.Message
获得价值?
像这样:
MainWindowViewModel viewModel = this.Resources["MainWindowViewModel"] as MainWindowViewModel;
//access any properties of viewModel here...