子视图中的 MVVM light 命令绑定损坏
MVVM light Command binding in childview broken
我无法让命令绑定在子视图中工作。我还想检查我打开子视图的方式是否正确。我已经坚持了一天了,我不确定这是我创建子视图还是绑定命令的方式。我还没有在主单选按钮上选择不同的选项时自动关闭子视图,有什么建议吗?
<Window x:Class="SimpleGui.Views.MainView"
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"
mc:Ignorable="d"
Title="Main" Height="450" Width="800">
<Grid Margin="10">
<DockPanel Grid.Column="2">
<Grid Height="403" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<StackPanel Margin="0,30,0,0">
<RadioButton Content="ChildView" Command="{Binding ShowChildCommand, Mode=TwoWay}"/>
<RadioButton Content="SomeOther"/>
</StackPanel>
</Grid>
</DockPanel>
</Grid>
</Window>
mainView.cs
using GalaSoft.MvvmLight.Messaging;
using System.Windows;
namespace SimpleGui.Views
{
public partial class MainView : Window
{
private static ChildView _childView = null;
public MainView()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowChildView")
{
if (_childView == null)
{
_childView= new ChildView();
_childView.Owner = Window.GetWindow(this);
_childView.Show();
}
_childView.Closed += _childView_Closed;
}
}
private void _childView_Closed(object sender, System.EventArgs e)
{
_childView = null;
}
}
}
MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Input;
namespace SimpleGui.ViewModels
{
public class MainViewModel: ViewModelBase
{
private ChildViewModel childViewModel;
public ICommand ShowChildCommand { get; set; } = new RelayCommand(ShowChild);
private static void ShowChild() => Messenger.Default.Send<NotificationMessage>(new NotificationMessage("ShowChildView"));
public MainViewModel()
{
childViewModel = new ChildViewModel(this);
}
}
}
ChildView.xaml
<Window x:Class="SimpleGui.Views.ChildView"
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:SimpleGui.ViewModels"
mc:Ignorable="d" Height="100" Width="200">
<Grid>
<Button
Content="Run"
DataContext="{Binding local.ChildViewModel}"
Command="{Binding runDemoCommand}"/>
</Grid>
</Window>
ChildView.cs
namespace SimpleGui.Views
{
public partial class ChildView : Window
{
public ChildView()
{
InitializeComponent();
}
}
}
最后是 childViewModel
namespace SimpleGui.ViewModels
{
public class ChildViewModel : ViewModelBase
{
public ICommand runDemoCommand { get; private set; }
public ChildViewModel(MainViewModel main)
{
runDemoCommand = new RelayCommand(runDemo);
}
public void runDemo()
{
MessageBox.Show("command running");
}
}
}
我用以下内容启动它:
var mainViewModel = new MainViewModel();
var window = new MainView();
window.DataContext = mainViewModel;
window.ShowDialog();
辅助 window 不会继承父 window 数据上下文,因此您需要明确设置它。
那么,让我们稍微修改一下您的代码:
mainView.cs
using GalaSoft.MvvmLight.Messaging;
using System.Windows;
namespace SimpleGui.Views
{
public partial class MainView : Window
{
private static ChildView _childView = null;
public MainView()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowChildView")
{
if (_childView == null)
{
_childView = new ChildView();
// Lets set the child view datacontext here
_childView.DataContext = new ChildViewModel ();
_childView.Owner = Window.GetWindow(this);
_childView.Show();
}
_childView.Closed += _childView_Closed;
}
}
private void _childView_Closed(object sender, System.EventArgs e)
{
_childView = null;
}
}
}
mainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Input;
namespace SimpleGui.ViewModels
{
public class MainViewModel: ViewModelBase
{
public ICommand ShowChildCommand { get; set; } = new RelayCommand(ShowChild);
private static void ShowChild() => Messenger.Default.Send<NotificationMessage>(new NotificationMessage("ShowChildView"));
public MainViewModel()
{
}
}
}
ChildView.Xaml
<Window x:Class="SimpleGui.Views.ChildView"
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:SimpleGui.ViewModels"
mc:Ignorable="d" Height="100" Width="200">
<Grid>
<!-- Now that the window has its own datacontext, it should be able to bind the command correctly -->
<Button Content ="Run"
Command="{Binding runDemoCommand}"/>
</Grid>
</Window>
我无法让命令绑定在子视图中工作。我还想检查我打开子视图的方式是否正确。我已经坚持了一天了,我不确定这是我创建子视图还是绑定命令的方式。我还没有在主单选按钮上选择不同的选项时自动关闭子视图,有什么建议吗?
<Window x:Class="SimpleGui.Views.MainView"
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"
mc:Ignorable="d"
Title="Main" Height="450" Width="800">
<Grid Margin="10">
<DockPanel Grid.Column="2">
<Grid Height="403" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<StackPanel Margin="0,30,0,0">
<RadioButton Content="ChildView" Command="{Binding ShowChildCommand, Mode=TwoWay}"/>
<RadioButton Content="SomeOther"/>
</StackPanel>
</Grid>
</DockPanel>
</Grid>
</Window>
mainView.cs
using GalaSoft.MvvmLight.Messaging;
using System.Windows;
namespace SimpleGui.Views
{
public partial class MainView : Window
{
private static ChildView _childView = null;
public MainView()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowChildView")
{
if (_childView == null)
{
_childView= new ChildView();
_childView.Owner = Window.GetWindow(this);
_childView.Show();
}
_childView.Closed += _childView_Closed;
}
}
private void _childView_Closed(object sender, System.EventArgs e)
{
_childView = null;
}
}
}
MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Input;
namespace SimpleGui.ViewModels
{
public class MainViewModel: ViewModelBase
{
private ChildViewModel childViewModel;
public ICommand ShowChildCommand { get; set; } = new RelayCommand(ShowChild);
private static void ShowChild() => Messenger.Default.Send<NotificationMessage>(new NotificationMessage("ShowChildView"));
public MainViewModel()
{
childViewModel = new ChildViewModel(this);
}
}
}
ChildView.xaml
<Window x:Class="SimpleGui.Views.ChildView"
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:SimpleGui.ViewModels"
mc:Ignorable="d" Height="100" Width="200">
<Grid>
<Button
Content="Run"
DataContext="{Binding local.ChildViewModel}"
Command="{Binding runDemoCommand}"/>
</Grid>
</Window>
ChildView.cs
namespace SimpleGui.Views
{
public partial class ChildView : Window
{
public ChildView()
{
InitializeComponent();
}
}
}
最后是 childViewModel
namespace SimpleGui.ViewModels
{
public class ChildViewModel : ViewModelBase
{
public ICommand runDemoCommand { get; private set; }
public ChildViewModel(MainViewModel main)
{
runDemoCommand = new RelayCommand(runDemo);
}
public void runDemo()
{
MessageBox.Show("command running");
}
}
}
我用以下内容启动它:
var mainViewModel = new MainViewModel();
var window = new MainView();
window.DataContext = mainViewModel;
window.ShowDialog();
辅助 window 不会继承父 window 数据上下文,因此您需要明确设置它。
那么,让我们稍微修改一下您的代码:
mainView.cs
using GalaSoft.MvvmLight.Messaging;
using System.Windows;
namespace SimpleGui.Views
{
public partial class MainView : Window
{
private static ChildView _childView = null;
public MainView()
{
InitializeComponent();
Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);
}
private void NotificationMessageReceived(NotificationMessage msg)
{
if (msg.Notification == "ShowChildView")
{
if (_childView == null)
{
_childView = new ChildView();
// Lets set the child view datacontext here
_childView.DataContext = new ChildViewModel ();
_childView.Owner = Window.GetWindow(this);
_childView.Show();
}
_childView.Closed += _childView_Closed;
}
}
private void _childView_Closed(object sender, System.EventArgs e)
{
_childView = null;
}
}
}
mainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using System.Windows.Input;
namespace SimpleGui.ViewModels
{
public class MainViewModel: ViewModelBase
{
public ICommand ShowChildCommand { get; set; } = new RelayCommand(ShowChild);
private static void ShowChild() => Messenger.Default.Send<NotificationMessage>(new NotificationMessage("ShowChildView"));
public MainViewModel()
{
}
}
}
ChildView.Xaml
<Window x:Class="SimpleGui.Views.ChildView"
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:SimpleGui.ViewModels"
mc:Ignorable="d" Height="100" Width="200">
<Grid>
<!-- Now that the window has its own datacontext, it should be able to bind the command correctly -->
<Button Content ="Run"
Command="{Binding runDemoCommand}"/>
</Grid>
</Window>