标签: relaycommand

10
推荐指数
3
解决办法
2万
查看次数

MVVM命令的"可执行"状态的编程重新评估

我正在使用MVVM模式编写WPF应用程序,基于以下文章:使用Model-View-ViewModel设计模式的WPF应用程序

我的View上有两个按钮,按钮的"Command"属性绑定(带数据绑定)到RelayCommand类的给定实例(参见上面文章中的"图3 RelayCommand类").RelayCommand类支持检查是否可以执行给定的命令.

WPF会自动禁用无法执行命令的按钮.

我的每个命令(在ViewModel类中)都启动后台操作,并且在后台操作完成之前无法再次执行该命令.RelayCommand实例具有后台操作是否仍在工作或已完成的信息.

我的问题如下:按下任意一个按钮后,按钮自动被禁用(这是正常的),因为后台操作已经开始,命令在完成之前无法执行,但是在操作完成后,按钮不会不会自动启用,因为它们的命令"可以执行"谓词不会自动重新评估.通过让应用程序松散并重新获得焦点(通过按ALT + TAB)可以手动触发重新评估.完成此操作后,按钮再次启用.

我怎样才能以编程方式重新评估按钮命令的"可以执行"状态?

wpf command mvvm relaycommand

10
推荐指数
1
解决办法
6282
查看次数

为什么RelayCommand RaiseCanExecuteChanged不能在单元测试中工作?

我正在使用Nuget(4.1.23.0)上可用的当前版本的MvvmLight,并且调用RaiseCanExecuteChanged似乎在单元测试中没有做任何事情.场景非常简单,我有一个命令:

public RelayCommand FooCommand { get; private set; }
Run Code Online (Sandbox Code Playgroud)

我在视图模型构造函数中新建它并将其指向一些私有方法:

FooCommand = new RelayCommand(Foo, CanFoo);

private void Foo()
{
    // do some fooing.
}

private bool CanFoo()
{
    return SomeRequiredProperty != null;
}
Run Code Online (Sandbox Code Playgroud)

然后在setter中SomeRequiredProperty我调用RaiseCanExecuteChanged:

public object SomeRequiredProperty
{
    get
    {
        return someRequiredProperty;
    }

    set
    {
        someRequiredProperty = value;
        FooCommand.RaiseCanExecuteChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在单元测试中,我执行以下操作:

// Arrange
var canExecuteChanged = false;
viewModel.FooCommand.CanExecuteChanged += (sender, args) => canExecuteChanged = true;

// Act
viewModel.SomeRequiredProperty = new object();

// Assert
Assert.That(canExecuteChanged, Is.True);
Run Code Online (Sandbox Code Playgroud)

测试失败,因为我的事件处理程序没有触发.这是为什么?

更新: …

c# wpf mvvm relaycommand mvvm-light

10
推荐指数
1
解决办法
2818
查看次数

一段时间后,RelayCommand停止工作

我使用GalaSoft的RelayCommand遇到了一些问题.

我有一个可以工作的NextCommand属性,但只有几次.

之后,它完全停止工作.

您可以使用示例项目尝试此操作:

http://s000.tinyupload.com/?file_id=65828891881629261404

行为如下:

  1. NextCommand:
    1. 弹出所有项目直到活动索引
    2. 如果剩下少于50个项目,则推送1个新项目
    3. 将新项目标记为活动
  2. BackCommand:
    1. 将活动索引向后移动1个位置

复制步骤:

  1. '+'(OemPlus)键已绑定到NextCommand
  2. ' - '(OemMinus)键已绑定到BackCommand
  3. 按住"+"键直到列表停止增长(限制50个项目)
  4. 按住" - "键,直到列表中的第一项处于活动状态
  5. 重复

所需的重复次数(复制错误)是不一致的.

有时我会在重复4次后得到它; 其他时间到9.

在此输入图像描述

// Items Collection
public class ItemCollection : ViewModelBase
{
    // List of Items
    private readonly ObservableCollection<Item> _items = new ObservableCollection<Item>();
    public ObservableCollection<Item> Items
    {
        get { return _items; }
    }

    // Constructor
    public ItemCollection()
    {
        BackCommand = new RelayCommand(
                () =>
                {
                    // Go to previous page
                    var index = Items.IndexOf(ActiveItem); …
Run Code Online (Sandbox Code Playgroud)

c# wpf relaycommand mvvm-light

10
推荐指数
1
解决办法
410
查看次数

如何将命令绑定到MenuItem(WPF)?

这是我在View.xaml.cs中的代码:

private RelayCommand _closeCommand;
public ICommand CloseCommand
{
    get
    {
        if (_closeCommand == null)
        {
            _closeCommand = new RelayCommand(param => this.OnClose());
        }
        return _closeCommand;
    }
}

public void OnClose()
{
    Close();
}
Run Code Online (Sandbox Code Playgroud)

以下是我的View.xaml中的一些代码:

<Window.ContextMenu>
    <ContextMenu>
        <MenuItem Name="menuItem_Close" Header="Close" Command="{Binding CloseCommand}" />
    </ContextMenu> 
</Window.ContextMenu>
Run Code Online (Sandbox Code Playgroud)

当我运行程序并选择关闭菜单项时,没有任何反应.CloseCommand代码甚至没有被执行.

data-binding wpf command menuitem relaycommand

9
推荐指数
1
解决办法
2万
查看次数

从CodeBehind绑定到VM的RelayCommand

我想知道我是否可以像这样在我的ViewModel上创建一个RelayCommand:

public RelayCommand<IList<VectorViewModel>> MyCommand { get; set; }
Run Code Online (Sandbox Code Playgroud)

构造函数:

MyCommand = new RelayCommand<IList<VectorViewModel>>(DoSomething);
Run Code Online (Sandbox Code Playgroud)

从XAML背后的代码中,我从DataGrid中获取所选行并将它们放入List中.

if (xamDatagridVector.SelectedItems.Records.Count >= 3)
{
                var list = new List<VectorViewModel>();
                foreach (DataRecord record in xamDatagridVector.SelectedItems.Records)
                {
                    list.Add((VectorViewModel)record.DataItem);
                }
}
Run Code Online (Sandbox Code Playgroud)

在这个阶段,我想通过使用我之前创建的RelayCommand将List发送回ViewModel.是否可以在代码中创建一个RelayCommand并将其绑定到ViewModel的命令并将其关闭?

有什么替代方式?我当然可以在MVVM-Light中使用弱引用的Messenger类,但是我不喜欢的是它会将它发送给该调用的所有订阅者,而不仅仅是底层的ViewModel(当你有几个时它使用Messenger是致命的TabControls中相同View的实例)

我希望有人有想法让我继续前进,非常感谢,Kave

.net wpf mvvm relaycommand mvvm-light

8
推荐指数
1
解决办法
9392
查看次数

为什么使用RelayCommand或DelegateCommand而不是仅仅实现ICommand?

我刚学习WPF中的MVVM,我对WPF和MVVM都是全新的(我理解它是如何工作的,但从未使用它......)

我在网上找到的每一篇教程/文章都使用了RelayCommand或DelegateCommand.

在我的观察中,这些模式迫使VM违反SRP原则,因为它将把命令逻辑保存在其中.

为什么不使用ICommand接口的自定义实现?像这样:

想象一下,您正在显示一个人并将其保存到数据库中:

我的Xaml就是这样的:

<StackPanel>                         
    <TextBlock Width="248" Height="24" Text="The name is:: " />
    <TextBlock Width="248" Height="24" Text="{Binding Name}">            
    </TextBlock>
    <TextBox HorizontalAlignment="Left" Name="textBox1" Width="120" Height="23" 
             VerticalAlignment="Top" Text="{Binding Name}"
             />
    <Button  Name="Salvar" VerticalAlignment="Bottom" 
            Command="{Binding SavePerson}" 
            CommandParameter="{Binding}">Save</Button>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

这是我的VM:

public class PersonVM: INotifyPropertyChanged
{
    private string nameValue;

    public string Name
    {
        get{
            return nameValue;
        }
        set
        {
            if (value != this.nameValue)
            {
                this.nameValue= value;
                NotifyPropertyChanged("Name");
            }
        }
    }


    public ICommand SavePerson{ get { return new SavePersonCommand(); } }
    #region INotifyPropertyChanged Members …
Run Code Online (Sandbox Code Playgroud)

wpf mvvm relaycommand delegatecommand

8
推荐指数
1
解决办法
5454
查看次数

使用IMultiValueConverter将多个CommandParameter传递给viewModel

我有以下代码:

<DataGridTemplateColumn Header="Security">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Name="Security" Content="{Binding Path=totalSecurities}" Command="{Binding Source={StaticResource viewModel}, Path=filterGridCommand}">
                                    <Button.CommandParameter>
                                        <MultiBinding Converter="{StaticResource PassThroughConverter}">
                                            <Binding Path="sector"/>
                                            <Binding ElementName="Security" Path="Name"/>
                                        </MultiBinding>
                                    </Button.CommandParameter>

                                </Button>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
Run Code Online (Sandbox Code Playgroud)

以下是PassThroughConverter的代码:

public class PassThroughConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameters, CultureInfo culture)
    {

        return values;
    }

    public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在命中返回值行时调试,正确的值在数组中,但是当我按下触发filtergrid命令的按钮时,返回的值都是null?谁能帮忙.谢谢.

.net wpf mvvm relaycommand imultivalueconverter

8
推荐指数
1
解决办法
2831
查看次数

当前上下文中不存在名称"CommandManager"(Visual Studio 2015)

尝试使用下面的RelayCommand类我收到错误消息:"名称"CommandManager"在当前上下文中不存在".根据这篇文章,类库无法识别CommandManager类,我试图通过在"添加引用"上添加一个名为PresentationCore的程序集来解决问题.不幸的是"机器上没有找到框架组件".我卸载了Microsoft.NETCore.UniversalWindowsPlatform并按照一些帖子中的建议重新安装它,我修复了Visual Studio,但这并没有改变任何东西.这是我的失败还是一个错误?作为一个新手,我总是倾向于认为我忽略了一些东西;-)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MyApplication.Viewmodels
{
public class RelayCommand : ICommand
{
    private readonly Action<object> _Execute;
    private readonly Func<object, bool> _CanExecute;

    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {

    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute", "Execute cannot be null.");
        }

        _Execute = execute;
        _CanExecute = canExecute;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; } …
Run Code Online (Sandbox Code Playgroud)

c# relaycommand visual-studio-2015

8
推荐指数
2
解决办法
2900
查看次数

RelayCommand的常见实现是否违反了MVVM模式?

一个非常常见的实现RelayCommand似乎包括以下几行:

public event EventHandler CanExecuteChanged
{
    add
    {
        CommandManager.RequerySuggested += value;
    }
    remove
    {
        CommandManager.RequerySuggested -= value;
    }
}
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎非常有缺陷,因为它CommandManager是一个WPF组件,通常我的命令位于viewmodel类中.由于viewmodel不应该知道视图并且应该使用不同的框架等,这对我来说似乎很奇怪.例如,如果将viewmodel分离到一个不知道WPF名称空间(例如PCL)的额外项目中,则甚至不可能实现此实现.

此实现是否违反了MVVM模式?
或者您可能会RelayCommand以某种方式放置在您的视图中?
如果确实存在缺陷,是否有解决此问题的最佳实践实施?

c# wpf mvvm relaycommand icommand

8
推荐指数
1
解决办法
1524
查看次数