gpt4 book ai didi

c# - 如何在 WPF 中使用多个 ViewModel 并通过一个 MainViewModel 绑定(bind)它们?

转载 作者:太空宇宙 更新时间:2023-11-03 17:31:36 25 4
gpt4 key购买 nike

我无法通过 MainViewModel 将 2 个 ViewModels 绑定(bind)到一个 View。

我的 MainWindow.xaml 如下所示:

<Window x:Class="Dojo4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:Dojo4.ViewModels"
Title="Dojo4" Height="346" Width="706">
<Window.DataContext>
<ViewModels:MainViewModel/>
</Window.DataContext>
<Grid>
<Button Content="Register" DataContext="{Binding RegisterViewModel}" Command="{Binding Register}" HorizontalAlignment="Left" Margin="19,63,0,0" VerticalAlignment="Top" Width="75"/>
<Label Content="Registration Name&#xD;&#xA;" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="25"/>
<Label Content="Field Size" HorizontalAlignment="Left" Margin="161,10,0,0" VerticalAlignment="Top" Height="25"/>
<Label Content="X" HorizontalAlignment="Left" Margin="161,35,0,0" VerticalAlignment="Top" Height="25"/>
<Label Content="Y" HorizontalAlignment="Left" Margin="203,35,0,0" VerticalAlignment="Top" Height="25"/>
<TextBox DataContext="{Binding RegisterViewModel}" Text="{Binding Name}" MaxLength="8" HorizontalAlignment="Left" Height="23" Margin="19,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
<TextBox DataContext="{Binding RegisterViewModel}" HorizontalAlignment="Left" Height="23" Margin="161,62,0,0" TextWrapping="Wrap" Text="{Binding X}" VerticalAlignment="Top" Width="23"/>
<TextBox DataContext="{Binding RegisterViewModel}" HorizontalAlignment="Left" Height="23" Margin="203,62,0,0" TextWrapping="Wrap" Text="{Binding Y}" VerticalAlignment="Top" Width="23"/>
<Button Content="Up" DataContext="{Binding PlayerControlViewModel}" Command="{Binding MovePlayer}" CommandParameter="up" HorizontalAlignment="Left" Margin="79,118,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
<Button Content="Down" DataContext="{Binding PlayerControlViewModel}" Command="{Binding MovePlayer}" CommandParameter="down" HorizontalAlignment="Left" Margin="79,226,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
<Button Content="Left" DataContext="{Binding PlayerControlViewModel}" Command="{Binding MovePlayer}" CommandParameter="left" HorizontalAlignment="Left" Margin="10,173,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="0.707,0.409" IsEnabled="False"/>
<Button Content="Right" DataContext="{Binding PlayerControlViewModel}" Command="{Binding MovePlayer}" CommandParameter="right" HorizontalAlignment="Left" Margin="145,173,0,0" VerticalAlignment="Top" Width="75" IsEnabled="False"/>
</Grid>

我的 MainViewModel 如下所示:

namespace Dojo4.ViewModels
{
class MainViewModel : BaseViewModel
{
private RegistrationViewModel _RegistrationViewModel;
public RegistrationViewModel RegistrationViewModel
{
get { return _RegistrationViewModel; }
}
private PlayerControlViewModel _PlayerControlViewModel;

public PlayerControlViewModel PlayerControlViewModel
{
get { return _PlayerControlViewModel; }
}

private GameModel _game;

public MainViewModel()
{
_game = new GameModel();
_PlayerControlViewModel = new PlayerControlViewModel(_game);
_RegistrationViewModel = new RegistrationViewModel(_game);
}
}
}

运行程序后,绑定(bind)将失败并出现以下错误:

System.Windows.Data Error: 40 : BindingExpression path error: 'Register' property not found on 'object' ''MainViewModel' (HashCode=51295333)'. BindingExpression:Path=Register; DataItem='MainViewModel' (HashCode=51295333); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand') System.Windows.Data Error: 40 : BindingExpression path error: 'RegisterViewModel' property not found on 'object' ''MainViewModel' (HashCode=51295333)'. BindingExpression:Path=RegisterViewModel; DataItem='MainViewModel' (HashCode=51295333); target element is 'Button' (Name=''); target property is 'DataContext' (type 'Object') System.Windows.Data Error: 40 : BindingExpression path error: 'RegisterViewModel' property not found on 'object' ''MainViewModel' (HashCode=51295333)'. BindingExpression:Path=RegisterViewModel; DataItem='MainViewModel' (HashCode=51295333); target element is 'TextBox' (Name=''); target property is 'DataContext' (type 'Object') System.Windows.Data Error: 40 : BindingExpression path error: 'RegisterViewModel' property not found on 'object' ''MainViewModel' (HashCode=51295333)'. BindingExpression:Path=RegisterViewModel; DataItem='MainViewModel' (HashCode=51295333); target element is 'TextBox' (Name=''); target property is 'DataContext' (type 'Object') System.Windows.Data Error: 40 : BindingExpression path error: 'RegisterViewModel' property not found on 'object' ''MainViewModel' (HashCode=51295333)'. BindingExpression:Path=RegisterViewModel; DataItem='MainViewModel' (HashCode=51295333); target element is 'TextBox' (Name=''); target property is 'DataContext' (type 'Object') System.Windows.Data Error: 40 : BindingExpression path error: 'MovePlayer' property not found on 'object' ''PlayerControlViewModel' (HashCode=65331996)'. BindingExpression:Path=MovePlayer; DataItem='PlayerControlViewModel' (HashCode=65331996); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand') System.Windows.Data Error: 40 : BindingExpression path error: 'MovePlayer' property not found on 'object' ''PlayerControlViewModel' (HashCode=65331996)'. BindingExpression:Path=MovePlayer; DataItem='PlayerControlViewModel' (HashCode=65331996); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand') System.Windows.Data Error: 40 : BindingExpression path error: 'MovePlayer' property not found on 'object' ''PlayerControlViewModel' (HashCode=65331996)'. BindingExpression:Path=MovePlayer; DataItem='PlayerControlViewModel' (HashCode=65331996); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand') System.Windows.Data Error: 40 : BindingExpression path error: 'MovePlayer' property not found on 'object' ''PlayerControlViewModel' (HashCode=65331996)'. BindingExpression:Path=MovePlayer; DataItem='PlayerControlViewModel' (HashCode=65331996); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')

看起来,DataContext 无法通过 MainViewModel 绑定(bind)到 ViewModels

最佳答案

您的代码中有拼写错误:RegisterViewModel 与 RegistrationViewModel。但也存在其他问题:

这段代码有问题DataContext="{Binding RegisterViewModel}"Command="{Binding Register}" 是,Command 属性上的绑定(bind)可能比 DataContext 绑定(bind)更早求值。

只需将 IsAsync=True 添加到命令绑定(bind):。

<Button DataContext="{Binding RegisterViewModel}"
Command="{Binding Register, IsAsync=True}" />

当您绑定(bind) datacontext 并且您还绑定(bind)同一元素的另一个属性(例如 Command 属性)时,您应该为除 datacontext 之外的所有绑定(bind)设置 IsAsync=True,这样 datacontext 将被更早地评估。


但是,您应该避免在元素上设置数据上下文,因为其他属性也被绑定(bind)了:

<Button Command="{Binding RegisterViewModel.Register}" />

因为你有多个元素数据绑定(bind)到同一个 View 模型,你应该通过 View 模型将它们分组到一个根元素,这样你的代码更具可读性和可维护性:

    <Grid DataContext="{Binding RegisterViewModel}" >
<Button Command="{Binding Register}" />
<Label Content="Registration Name&#xD;&#xA;"/>
<Label Content="Field Size" />
<Label Content="X" />
<Label Content="Y" />
<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding X}" />
<TextBox Text="{Binding Y}" />
</Grid>
<Grid DataContext="{Binding PlayerControlViewModel}">
<Button Command="{Binding MovePlayer}" CommandParameter="up" />
<Button Command="{Binding MovePlayer}" CommandParameter="down"/>
<Button Command="{Binding MovePlayer}" CommandParameter="left" />
<Button Command="{Binding MovePlayer}" CommandParameter="right" />
</Grid>

注意这如何有助于避免违反“不要重复自己”原则的最简单形式。我不会一直重复数据上下文绑定(bind)

关于c# - 如何在 WPF 中使用多个 ViewModel 并通过一个 MainViewModel 绑定(bind)它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20167738/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com