将按钮绑定到 Wpf MVVMLight 中的 RelayCommand
Binding button to RelayCommand in Wpf MVVMLight
你好,我正在做一个 Wpf MVVM 项目,但我不知道如何将 Xaml 中带有 Command 属性的按钮绑定到 Viewmodel 中的 RelayCommand,我在网上找到了多个答案,但是我不明白(实现 ICommand 接口和 canexecute 等等......),问题是我有一个已经由其他开发人员制作的项目,他们简单地在 Xaml 中绑定按钮,就像这样:
这是视图中的完整代码:
<Window x:Class="MvvmLight3.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:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
xmlns:ignore="http://www.galasoft.ch/ignore"
mc:Ignorable="d ignore"
Height="300"
Width="300"
Title="MVVM Light Application"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" ><Run Text="WelcomeTitle"/><InlineUIContainer>
<Label Content="{Binding welcome}"/>
</InlineUIContainer></TextBlock>
<Button Content="Button" Command="{Binding The_Command}" HorizontalAlignment="Left" Margin="170,80,0,0" VerticalAlignment="Top" Width="75">
</Button>
</Grid>
在 ViewModel 中,完整代码是:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using MvvmLight3.Model;
using System.Windows.Input;
namespace MvvmLight3.ViewModel
{
/// <summary>
/// This class contains properties that the main View can data bind to.
/// <para>
/// See http://www.mvvmlight.net
/// </para>
/// </summary>
public class MainViewModel : ViewModelBase
{
private readonly IDataService _dataService;
/// <summary>
/// The <see cref="WelcomeTitle" /> property's name.
/// </summary>
public const string WelcomeTitlePropertyName = "WelcomeTitle";
private string _welcomeTitle = string.Empty;
private string _welcome = "this work";
/// <summary>
/// Gets the WelcomeTitle property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string WelcomeTitle
{
get
{
return _welcomeTitle;
}
set
{
Set(ref _welcomeTitle, value);
}
}
public string welcome
{
get
{
return _welcome;
}
set
{
Set(ref _welcome, value);
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
if (error != null)
{
// Report error here
return;
}
WelcomeTitle = item.Title;
});
}
private RelayCommand _The_Command;
public RelayCommand The_Command
{
get
{
return _The_Command
?? (_The_Command = new RelayCommand(
() =>
{
//some Code
}));
}
}
////public override void Cleanup()
////{
//// // Clean up if needed
//// base.Cleanup();
////}
}
}
在我的例子中,执行不进入 RelayCommand。
代码在ViewModelLocator.cs
/*
In App.xaml:
<Application.Resources>
<vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:MvvmLight3.ViewModel"
x:Key="Locator" />
</Application.Resources>
In the View:
DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
*/
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using MvvmLight3.Model;
namespace MvvmLight3.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/// <para>
/// See http://www.mvvmlight.net
/// </para>
/// </summary>
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{
}
}
}
该项目是 MVVMLight (wpf451) 模板。
谢谢。
它起作用了,这有点傻,实际上如果你注意到我的中继命令 (The_Command) 是空的,尽管它里面有注释 (//some Code),get 上的断点或 return 当我点击按钮时从未经历过。
解决方法:
在我在命令中添加一个功能代码后它起作用了:例如添加了一个简单的 MessageBox.Show。所以绑定是正确的。对于我使用的信息 VisualStudio Enterprise 2017 。
你好,我正在做一个 Wpf MVVM 项目,但我不知道如何将 Xaml 中带有 Command 属性的按钮绑定到 Viewmodel 中的 RelayCommand,我在网上找到了多个答案,但是我不明白(实现 ICommand 接口和 canexecute 等等......),问题是我有一个已经由其他开发人员制作的项目,他们简单地在 Xaml 中绑定按钮,就像这样:
这是视图中的完整代码:
<Window x:Class="MvvmLight3.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:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
xmlns:ignore="http://www.galasoft.ch/ignore"
mc:Ignorable="d ignore"
Height="300"
Width="300"
Title="MVVM Light Application"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" ><Run Text="WelcomeTitle"/><InlineUIContainer>
<Label Content="{Binding welcome}"/>
</InlineUIContainer></TextBlock>
<Button Content="Button" Command="{Binding The_Command}" HorizontalAlignment="Left" Margin="170,80,0,0" VerticalAlignment="Top" Width="75">
</Button>
</Grid>
在 ViewModel 中,完整代码是:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using MvvmLight3.Model;
using System.Windows.Input;
namespace MvvmLight3.ViewModel
{
/// <summary>
/// This class contains properties that the main View can data bind to.
/// <para>
/// See http://www.mvvmlight.net
/// </para>
/// </summary>
public class MainViewModel : ViewModelBase
{
private readonly IDataService _dataService;
/// <summary>
/// The <see cref="WelcomeTitle" /> property's name.
/// </summary>
public const string WelcomeTitlePropertyName = "WelcomeTitle";
private string _welcomeTitle = string.Empty;
private string _welcome = "this work";
/// <summary>
/// Gets the WelcomeTitle property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string WelcomeTitle
{
get
{
return _welcomeTitle;
}
set
{
Set(ref _welcomeTitle, value);
}
}
public string welcome
{
get
{
return _welcome;
}
set
{
Set(ref _welcome, value);
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
if (error != null)
{
// Report error here
return;
}
WelcomeTitle = item.Title;
});
}
private RelayCommand _The_Command;
public RelayCommand The_Command
{
get
{
return _The_Command
?? (_The_Command = new RelayCommand(
() =>
{
//some Code
}));
}
}
////public override void Cleanup()
////{
//// // Clean up if needed
//// base.Cleanup();
////}
}
}
在我的例子中,执行不进入 RelayCommand。
代码在ViewModelLocator.cs
/*
In App.xaml:
<Application.Resources>
<vm:ViewModelLocatorTemplate xmlns:vm="clr-namespace:MvvmLight3.ViewModel"
x:Key="Locator" />
</Application.Resources>
In the View:
DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}"
*/
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using MvvmLight3.Model;
namespace MvvmLight3.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/// <para>
/// See http://www.mvvmlight.net
/// </para>
/// </summary>
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
SimpleIoc.Default.Register<MainViewModel>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
/// <summary>
/// Cleans up all the resources.
/// </summary>
public static void Cleanup()
{
}
}
}
该项目是 MVVMLight (wpf451) 模板。 谢谢。
它起作用了,这有点傻,实际上如果你注意到我的中继命令 (The_Command) 是空的,尽管它里面有注释 (//some Code),get 上的断点或 return 当我点击按钮时从未经历过。
解决方法: 在我在命令中添加一个功能代码后它起作用了:例如添加了一个简单的 MessageBox.Show。所以绑定是正确的。对于我使用的信息 VisualStudio Enterprise 2017 。