尝试启用一个依赖于文本框内容的按钮 [英] Trying to enable a button dependent on content of textbox

查看:40
本文介绍了尝试启用一个依赖于文本框内容的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

我坚持认为这是一个简单的问题.我希望根据文本框的内容来启用/禁用按钮.该按钮绑定到DelegateCommand.

这是我的XAML:

Hello,

I''m stuck with I think is a simple problem. I want a button to be enabled/disabled depending on the content of a textbox. The button is bound to a DelegateCommand.

This is my XAML:

<Window x:Class="EnableButtonTest.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" Height="200" Width="225">
    <Grid>
        <TextBox Text="{Binding Path=Content}" Height="23" HorizontalAlignment="Left" Margin="68,28,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
        <Button Command="{Binding Path=Click}" Content="Button" Height="23" HorizontalAlignment="Left" Margin="80,72,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>



这是我的代码背后:



This is my code behind:

namespace EnableButtonTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        internal Presenter myPresenter = new Presenter();
        public MainWindow()
        {
            DataContext = myPresenter;
            InitializeComponent();
        }
    }
}



这是我的主持人:



And this is my presenter:

namespace EnableButtonTest
{
    public class Presenter : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _Content;
        public string Content
        {
            get { return _Content; }
            set { 
                _Content = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Content"));
                }
            }
        }

        public ICommand Click { get; private set; }

        public Presenter()
        {
            Click = new DelegateCommand(ExecuteTest, CanExecuteTest);
        }
        public void ExecuteTest()
        {
        }
        public bool CanExecuteTest()
        {
            return !string.IsNullOrWhiteSpace(Content);
        }
    }
}



我可以在文本框中输入内容,但Presenter似乎没有收到通知.

我想念什么或做错什么了?

感谢您的阅读,

Stefan



I can enter content in the textbox but the Presenter doesn''t seem to get notified.

What am I missing or doing wrong?

Thanks for reading,

Stefan

推荐答案

下面是对代码的快速修复:

Here is a quick fix to your code:

public class Presenter : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  private string _Content;
  public string Content
  {
    get { return _Content; }
    set
    {
      _Content = value;
      if (PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs("Content"));
      }
      Click.RaiseCanExecuteChanged();
    }
  }

  public DelegateCommand Click { get; private set; }

  public Presenter()
  {
    Click = new DelegateCommand(ExecuteTest, CanExecuteTest);
  }
  public void ExecuteTest()
  {
  }
  public bool CanExecuteTest()
  {
    return !string.IsNullOrWhiteSpace(Content);
  }
}



您需要执行RaiseCanExecuteChanged.请注意,在某些情况下,这也不起作用.现在,我将进行更极端的修复:



You need to do the RaiseCanExecuteChanged. Note that in some situations even this will not work. Now I will do a more extreme fix:

public class Presenter : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
  private string _content;
  public string Content
  {
    get { return _content; }
    set
    {
      if (_content != value)
      {
        _content = value;
        if (PropertyChanged != null)
        {
          PropertyChanged(this, new PropertyChangedEventArgs("Content"));
        }
        Click.RaiseCanExecuteChanged();
      }
    }
  }

  public DelegateCommand Click
  {
    get
    {
      return new DelegateCommand(
        () =>
        {
          /*Execute Test*/
        },
          () => !string.IsNullOrWhiteSpace(Content)
      );
    }
  }
}



这意味着仅在实际更改值的情况下才触发PropertyChanged到RaiseCanExecuteChanged.还将所有Click代码放在一个位置.但这仍然不是线程安全的,但可能不是问题.

我仍然不认为这是完美的,因为您必须更频繁地触发RaiseCanExecuteChanged.



This would mean that only fire the PropertyChanged an RaiseCanExecuteChanged if the value has actually changed. It also puts all the Click code in one place. Still this is not thread safe, but probably not an issue.

I would still not consider this perfect since firing RaiseCanExecuteChanged more often then you have to.


Window.xaml
Window.xaml
<window x:class="CPTest.Window1" xmlns:x="#unknown">
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="225">
    <grid>
        <textbox text="{Binding Path=Content, UpdateSourceTrigger=PropertyChanged}" height="23" horizontalalignment="Left" margin="68,28,0,0" name="textBox1" verticalalignment="Top" width="120" acceptsreturn="False" />
        <button command="{Binding Path=Click}" content="Button" height="23" horizontalalignment="Left" margin="80,72,0,0" name="button1" verticalalignment="Top" width="75" />
    </grid>
</window>



Window.cs



Window.cs

namespace CPTest
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        internal Presenter myPresenter = new Presenter();
        public Window1()
        {
            InitializeComponent();
            DataContext = myPresenter;
        }
    }
}



Presenter.cs



Presenter.cs

namespace CPTest
{
    class Presenter : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        private string _Content;
        public string Content
        {
            get { return _Content; }
            set
            {
                _Content = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Content"));
                }
            }
        }
        public ICommand Click { get; private set; }
        public Presenter()
        {
            Click = new DelegateCommand(ExecuteTest, CanExecuteTest);
        }
        public void ExecuteTest(object obj)
        {
        }
        public bool CanExecuteTest(object obj)
        {
            return !string.IsNullOrEmpty(Content);
        }
    }
}



如果您的CanExecuteTest没有被一遍又一遍地调用,那么我怀疑您的DelegateCommand类代码有问题.

为了完整起见,我的DelegateCommand代码已包含在此处.



If your CanExecuteTest is not getting called over and over then I suspect there is something wrong with your DelegateCommand class code.

My code for DelegateCommand is included here for completeness.

class DelegateCommand : ICommand
    {
        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;
        public DelegateCommand(Action<object> execute)
            : this(execute, null)
        {
        }
        public DelegateCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");
            _execute = execute;
            _canExecute = canExecute;
        }
        public void Execute(object parameter)
        {
            _execute(parameter);
        }
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute(parameter);
        }
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    }


这篇关于尝试启用一个依赖于文本框内容的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆