WPF 数据绑定与 ResourceDictionary MVVM
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14102310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Data binding with ResourceDictionary MVVM
提问by shadox
I'm trying to bind a View with a ViewModel within ResourceDictionary but it does not work.
我正在尝试将 View 与 ResourceDictionary 中的 ViewModel 绑定,但它不起作用。
The application is very simple window with 2 textboxes. When I type text to textbox1, atutomatically, textbox2 must get the same text. Of course my textboxes from the View have to be binded to my properties in ViewModel.
该应用程序是一个非常简单的窗口,带有 2 个文本框。当我向 textbox1 键入文本时,自动地,textbox2 必须获得相同的文本。当然,View 中的文本框必须绑定到 ViewModel 中的属性。
I'm new to WPF and the way I started to bind Views and ViewModels was in the codebehind of a View:
我是 WPF 的新手,我开始绑定视图和视图模型的方式是在视图的代码隐藏中:
DataContext = new MyViewModel();
Now I'm trying to achieve a cleaner separation. My code is
现在我正在努力实现更清晰的分离。我的代码是
App.xaml:
应用程序.xaml:
<Application x:Class="NavigationCleanBinding.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="/Views/MainWindowView.xaml">
<Application.Resources>
<ResourceDictionary Source="MainResourceDictionary.xaml" />
</Application.Resources>
</Application>
MainResourceDictionary.xaml:
MainResourceDictionary.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xamlpresentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Views="clr-namespace:NavigationCleanBinding.Views"
xmlns:ViewModels="clr-namespace:NavigationCleanBinding.ViewModels">
<DataTemplate DataType="{x:Type ViewModels:MainWindowViewModel}">
<Views:MainWindowView />
</DataTemplate>
</ResourceDictionary>
MainWindowView.xaml:
主窗口视图.xaml:
<Window x:Class="NavigationCleanBinding.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox Height="23" HorizontalAlignment="Left" Margin="61,14,0,0"
Name="textBox1" VerticalAlignment="Top" Width="120"
Text="{Binding TestData, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Test:" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0"
Name="label1" VerticalAlignment="Top" Width="43" />
<Label Content="Result:" Height="28" HorizontalAlignment="Left" Margin="10,46,0,0"
Name="label2" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="61,48,0,0"
Name="textBox2" VerticalAlignment="Top" Width="120"
Text="{Binding TestData, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
MainWindowViewModel:
主窗口视图模型:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NavigationCleanBinding.ViewModels
{
class MainWindowViewModel
{
private String _testData;
public String TestData
{
get { return _testData; }
set { _testData = value; }
}
private MainWindowViewModel()
{
_testData = null;
}
}
}
UPDATE:
更新:
I changed property TestData to this:
我将属性 TestData 更改为:
public String TestData
{
get { return _testData; }
set
{
_testData = value;
OnPropertyChanged("TestData");
}
}
And implemened the INotifyPropertyChanged like this:
并像这样实现了 INotifyPropertyChanged:
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
采纳答案by TheZenker
so user1064519 was on the right track:
所以 user1064519 是在正确的轨道上:
- the View needs to be a
UserControl, not aWindow, as it is hosted in the MainWindow the ViewModel needs to be loaded into the MainWindow, this is what triggers the
DataTemplateto be discovered and loaded.<Window x:Class="WpfTemplateBootstrap.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfTemplateBootstrap" Title="MainWindow" Height="350" Width="525"> <ContentControl> <ContentControl.Content> <local:MainWindowViewModel /> </ContentControl.Content> </ContentControl>
- View 需要是 a
UserControl,而不是 aWindow,因为它托管在 MainWindow 中 ViewModel 需要加载到 MainWindow 中,这是触发
DataTemplate被发现和加载的原因。<Window x:Class="WpfTemplateBootstrap.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfTemplateBootstrap" Title="MainWindow" Height="350" Width="525"> <ContentControl> <ContentControl.Content> <local:MainWindowViewModel /> </ContentControl.Content> </ContentControl>
After that you should be up and running. I have posted an in-depth example here: wpf bootstrapping datatemplates--the chicken and the egg
之后,您应该启动并运行。我在这里发布了一个深入的例子:wpf bootstrapping datatemplates--the chicken and the egg
回答by Kamolas81
Your ViewModel must implement the interface INotifyPropertyChangedand raise a PropertyChangedevent when any binded property value changes, so that your view can know that changes ocurred.
您的 ViewModel 必须实现该接口INotifyPropertyChanged并PropertyChanged在任何绑定的属性值更改时引发事件,以便您的视图可以知道发生了更改。
回答by user1064519
DataTemplate sholudnt contain window, it can contains any kind of control.
DataTemplate 不应该包含窗口,它可以包含任何类型的控件。
DataTemplate :
数据模板:
<DataTemplate DataType="{x:Type ViewModels:MainWindowViewModel}">
<Views:MainWindowView />
</DataTemplate>
UserControl :
用户控制:
<UserControl x:Class="NavigationCleanBinding.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="525">
<Grid>
<TextBox Height="23" HorizontalAlignment="Left" Margin="61,14,0,0"
Name="textBox1" VerticalAlignment="Top" Width="120"
Text="{Binding TestData, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Test:" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0"
Name="label1" VerticalAlignment="Top" Width="43" />
<Label Content="Result:" Height="28" HorizontalAlignment="Left" Margin="10,46,0,0"
Name="label2" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="61,48,0,0"
Name="textBox2" VerticalAlignment="Top" Width="120"
Text="{Binding TestData, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</UserControl>
Window :
窗户 :
<Window x:Class="NavigationCleanBinding.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<ContentControl Content={Binding}/>
</Window>

