【问题标题】:Why does DelegateCommand not work the same for Button and MenuItem?为什么 DelegateCommand 对 Button 和 MenuItem 的工作方式不同?
【发布时间】:2009-06-05 09:48:54
【问题描述】:

这段代码表明Delegate Command from the Visual Studio MVVM template 与 MenuItem 和 Button 一起使用时的工作方式不同:

  • 使用 Button,命令方法可以访问 ViewModel 上已更改的 OnPropertyChanged 值
  • 但是,当使用 MenuItem 时,命令方法无法访问已更改的 OnPropertyChanged 值

有人知道为什么会这样吗?

MainView.xaml:

<Window x:Class="TestCommand82828.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:c="clr-namespace:TestCommand82828.Commands"
    Title="Main Window" Height="400" Width="800">

    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Command="{Binding DoSomethingCommand}" Header="Do Something" />
            </MenuItem>
        </Menu>
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">
            <Button Command="{Binding DoSomethingCommand}" Content="test"/>
            <TextBlock Text="{Binding Output}"/>
            <TextBox Text="{Binding TheInput}"/>
        </StackPanel>

    </DockPanel>
</Window>

MainViewModel.cs:

using System;
using System.Windows;
using System.Windows.Input;
using TestCommand82828.Commands;

namespace TestCommand82828.ViewModels
{
    public class MainViewModel : ViewModelBase
    {
        #region ViewModelProperty: TheInput
        private string _theInput;
        public string TheInput
        {
            get
            {
                return _theInput;
            }

            set
            {
                _theInput = value;
                OnPropertyChanged("TheInput");
            }
        }
        #endregion

        #region DelegateCommand: DoSomething
        private DelegateCommand doSomethingCommand;

        public ICommand DoSomethingCommand
        {
            get
            {
                if (doSomethingCommand == null)
                {
                    doSomethingCommand = new DelegateCommand(DoSomething, CanDoSomething);
                }
                return doSomethingCommand;
            }
        }

        private void DoSomething()
        {
            Output = "did something, the input was: " + _theInput;
        }

        private bool CanDoSomething()
        {
            return true;
        }
        #endregion            

        #region ViewModelProperty: Output
        private string _output;
        public string Output
        {
            get
            {
                return _output;
            }

            set
            {
                _output = value;
                OnPropertyChanged("Output");
            }
        }
        #endregion

    }
}

【问题讨论】:

    标签: mvvm delegatecommand


    【解决方案1】:

    我认为您所看到的是因为 MenuItems 不会将焦点从 TextBox 移开,并且默认情况下,TextBox 只会在焦点从其移开时将更改推回其绑定源。因此,当您单击按钮时,焦点转移到按钮上,将 TextBox 的值写回 _theInput。但是,当您单击 MenuItem 时,焦点仍保留在 TextBox 中,因此不会写入值。

    尝试将您的 TextBox 声明更改为:

    <TextBox Text="{Binding TheInput,UpdateSourceTrigger=PropertyChanged}"/>
    

    或者,尝试切换到DelegateCommand&lt;t&gt;,它可以接收参数,并将TextBox的文本传递给它:

    <MenuItem Command="{Binding DoSomethingCommand}" 
              CommandParameter="{Binding Text,ElementName=inputTextBox}" />
    ...
    <TextBox x:Name="inputTextBox" Text="{Binding TheInput}" />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-23
      • 2014-06-20
      • 2010-11-29
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      相关资源
      最近更新 更多