通过资源设置数据上下文
Setting a datacontext via resources
显然使用“Resources”设置控件的 DataContext 与我想的不一样。我试图贴近 MVVM。下面是设置DataContext的实验。
MainWindow 有一个带有两个选项卡的 TabControl,每个选项卡都显示我宠物的名字,最初是“Sam”。单击选项卡 1 上的“ChangeName”按钮可按预期更改宠物的名称(更改为“Daisy”)。它在选项卡 2 上没有变化。
Tab 2 的内容是一个Page,有自己的DataContext,SecondTabViewModel。所以我需要调整 TextBlock 中的 DataContext 以获取 MyPet 的名称。这编译正常,并且 Intellisense 提出了正确的事情,因此以某种方式在控件内进行了设置。但是宠物的名字没有变。
“StaticResource”是否生成实例化 MainWindow 或其他东西的新副本?有人可以帮我吗?我很想知道为什么这不起作用, 会起作用。根据 https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/?view=netdesktop-5.0 上的文档,这种设置本地 DataContext 的策略应该有效,但我一定是误读了。
简而言之,我省略了一些代码(宠物 class。但是那里似乎一切正常,因为我可以更改第一个选项卡上的名称 The Pet class 实现 INotifyPropertyChanged,我正在使用正确的处理程序等)
MainWindow.xmal
<Window x:Class="WpfApp9.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp9"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<TabControl>
<TabItem Header="First Tab" Height="50">
<StackPanel>
<TextBlock Text="{Binding MyPet.Name}"/>
<Button Content="Change Name"
Command="{Binding ChangePetNameCommand}"/>
</StackPanel>
</TabItem>
<TabItem Header="Second Tab" Height="50">
<Frame Source="SecondTab.xaml"/>
</TabItem>
</TabControl>
</Grid>
</Window>
MainWindowViewModel
public class MainWindowViewModel
{
public Pet MyPet { get; set; }
public ICommand ChangePetNameCommand { get; set; }
public MainWindowViewModel()
{
MyPet = new Pet();
ChangePetNameCommand =
new RelayCommand(ChangePetName, (Object o) => true);
}
public void ChangePetName(object o)
{
MyPet.Name = "Daisy";
}
}
SecondTab.xmal
<Page x:Class="WpfApp9.SecondTab"
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"
xmlns:local="clr-namespace:WpfApp9"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="SecondTab">
<Page.DataContext>
<local:SecondTabViewModel/>
</Page.DataContext>
<Page.Resources>
<local:MainWindowViewModel x:Key="M"/>
</Page.Resources>
<Grid>
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource M},
Path = MyPet.Name}"/>
</StackPanel>
</Grid>
</Page>
SecondTabviewModel
namespace WpfApp9
{
public class SecondTabViewModel
{
public SecondTabViewModel()
{
}
}
}
线条
<Page.Resources>
<local:MainWindowViewModel x:Key="M"/>
</Page.Resources>
在 SecondTab.xaml 中正在创建第二个 MainWindowViewModel 实例。
也就是说SecondTab并没有对原来的MainWindowViewModel进行操作
您将不得不以某种方式将对原始 MainWindowViewModel 实例的引用传递给 SecondTabViewModel。
SecondTab 可能不是使用 Frame 和 Page,而是简单地从其父元素继承 DataContext 的 UserControl,并且您可以传递一个视图模型对象,例如
<TabItem Header="Second Tab" Height="50">
<local:SecondTab DataContext="{Binding SecondTabVM}"/>
</TabItem>
其中 SecondTabVM
是包含 SecondTabViewModel 实例的 MainWindowViewModel 的 属性。
显然使用“Resources”设置控件的 DataContext 与我想的不一样。我试图贴近 MVVM。下面是设置DataContext的实验。
MainWindow 有一个带有两个选项卡的 TabControl,每个选项卡都显示我宠物的名字,最初是“Sam”。单击选项卡 1 上的“ChangeName”按钮可按预期更改宠物的名称(更改为“Daisy”)。它在选项卡 2 上没有变化。
Tab 2 的内容是一个Page,有自己的DataContext,SecondTabViewModel。所以我需要调整 TextBlock 中的 DataContext 以获取 MyPet 的名称。这编译正常,并且 Intellisense 提出了正确的事情,因此以某种方式在控件内进行了设置。但是宠物的名字没有变。
“StaticResource”是否生成实例化 MainWindow 或其他东西的新副本?有人可以帮我吗?我很想知道为什么这不起作用, 会起作用。根据 https://docs.microsoft.com/en-us/dotnet/desktop/wpf/data/?view=netdesktop-5.0 上的文档,这种设置本地 DataContext 的策略应该有效,但我一定是误读了。
简而言之,我省略了一些代码(宠物 class。但是那里似乎一切正常,因为我可以更改第一个选项卡上的名称 The Pet class 实现 INotifyPropertyChanged,我正在使用正确的处理程序等)
MainWindow.xmal
<Window x:Class="WpfApp9.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp9"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<TabControl>
<TabItem Header="First Tab" Height="50">
<StackPanel>
<TextBlock Text="{Binding MyPet.Name}"/>
<Button Content="Change Name"
Command="{Binding ChangePetNameCommand}"/>
</StackPanel>
</TabItem>
<TabItem Header="Second Tab" Height="50">
<Frame Source="SecondTab.xaml"/>
</TabItem>
</TabControl>
</Grid>
</Window>
MainWindowViewModel
public class MainWindowViewModel
{
public Pet MyPet { get; set; }
public ICommand ChangePetNameCommand { get; set; }
public MainWindowViewModel()
{
MyPet = new Pet();
ChangePetNameCommand =
new RelayCommand(ChangePetName, (Object o) => true);
}
public void ChangePetName(object o)
{
MyPet.Name = "Daisy";
}
}
SecondTab.xmal
<Page x:Class="WpfApp9.SecondTab"
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"
xmlns:local="clr-namespace:WpfApp9"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="SecondTab">
<Page.DataContext>
<local:SecondTabViewModel/>
</Page.DataContext>
<Page.Resources>
<local:MainWindowViewModel x:Key="M"/>
</Page.Resources>
<Grid>
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource M},
Path = MyPet.Name}"/>
</StackPanel>
</Grid>
</Page>
SecondTabviewModel
namespace WpfApp9
{
public class SecondTabViewModel
{
public SecondTabViewModel()
{
}
}
}
线条
<Page.Resources>
<local:MainWindowViewModel x:Key="M"/>
</Page.Resources>
在 SecondTab.xaml 中正在创建第二个 MainWindowViewModel 实例。
也就是说SecondTab并没有对原来的MainWindowViewModel进行操作
您将不得不以某种方式将对原始 MainWindowViewModel 实例的引用传递给 SecondTabViewModel。
SecondTab 可能不是使用 Frame 和 Page,而是简单地从其父元素继承 DataContext 的 UserControl,并且您可以传递一个视图模型对象,例如
<TabItem Header="Second Tab" Height="50">
<local:SecondTab DataContext="{Binding SecondTabVM}"/>
</TabItem>
其中 SecondTabVM
是包含 SecondTabViewModel 实例的 MainWindowViewModel 的 属性。