【问题标题】:using INotifyPropertyChanged how to Click wpf button使用 INotifyPropertyChanged 如何单击 wpf 按钮
【发布时间】:2017-12-02 21:08:28
【问题描述】:

我需要在日期更改时更新 wpf listview。我已经编写了在单击按钮时更新列表视图的方法。使用 INotifyPropertyChanged 在日期更改时触发相同的按钮。我有以下代码,但需要帮助才能单击相同的按钮或任何其他方法。

这是需要点击的wpf按钮。 <Button x:Name="SearchButton" Content="Search" HorizontalAlignment="Left" Margin="344,161,0,0" VerticalAlignment="Top" Click="SearchButton_Click" FontSize="18" FontWeight="Bold" />

 public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = clock;
        clock.InitClock(); //using another INotifyPropertyChanged to update clock on textbox
        cDate.dateInitClock();
}

public class ChangeDate : INotifyPropertyChanged
{
    DispatcherTimer dateTimer = new DispatcherTimer();

    public string _date { get; set; }
    public string Date
    {
        get { return _date; }
        set
        {
            _date = value;
            OnPropertyChanged("Date");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string date)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(date));
        }
    }

    public void dateInitClock()
    {
        dateTimer.Tick += dateTimer_Tick;
        dateTimer.Interval = new TimeSpan(0, 0, 1, 0);
        dateTimer.Start();
    }

    private void dateTimer_Tick(object sender, object e)
    {
        // do we need to add action here?
    }

}

【问题讨论】:

  • 你不点击(事件)你执行了一个命令(Command={Binding YourCommand
  • 你能帮我在按钮中添加什么命令吗?
  • 完成,请看下面的答案

标签: c# wpf inotifypropertychanged


【解决方案1】:

最后编辑:Here 一个链接到一个工作解决方案,用于更新ListView 中的列 (计时器每秒增加 1 分钟)


首先为你的中继命令创建一个类

using System;
using System.Diagnostics;
using System.Windows.Input;

public class RelayCommand : ICommand
    {
        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;

        #region Constructors

        /// <summary>
        /// Creates a new command.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        /// <param name="canExecute">The execution status logic.</param>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }
        #endregion // Constructors

        #region ICommand Members
        [DebuggerStepThrough]
        public bool CanExecute(object parameter)
        {
            //For Vs 2015+ 
            return _canExecute?.Invoke(parameter) ?? true;
            //For Vs 2013-
            return _canExecute != null ? _canExecute.Invoke(parameter) : true;
        }

        /// <summary>
        /// Can execute changed event handler.
        /// </summary>
        public event EventHandler CanExecuteChanged
        {
            add => CommandManager.RequerySuggested += value;
            remove => CommandManager.RequerySuggested -= value;
        }

        public void Execute(object parameter)
        {
            _execute(parameter);
        }
        #endregion // ICommand Members
    }

然后你可以直接从你的ViewModel执行你的命令

//with some validation to enable/disable button click

public virtual ICommand SearchCommand => new RelayCommand(o=> Search(), o=> Validation());

//without validation

 public virtual ICommand SearchCommand => new RelayCommand(o=> Search());

private void Search()
{

}

private bool Validation()
{

}

//using parametres
public virtual ICommand SearchCommand => new RelayCommand(Search);
private void Search(object parameter)
{

}

你的 XAML

<Button Content="Search"  Command={Binding SearchCommand}  />

使用 MVVM 绑定ListView 的示例

<ListView ItemsSource="{Binding Path=YourData}">
    <ListView.View>
         <GridView>
             <GridViewColumn Header="ID" Width="Auto" 
                  DisplayMemberBinding="{Binding ID}" >
             </GridViewColumn>
             <GridViewColumn DisplayMemberBinding="{Binding Name}" 
                  Header="Name" Width="100"/>
             <GridViewColumn DisplayMemberBinding="{Binding Price}" 
                  Header="Price" Width="100"/>
             <GridViewColumn DisplayMemberBinding="{Binding Author}" 
                  Header="Author" Width="100"/>
             <GridViewColumn DisplayMemberBinding="{Binding Catalog}" 
                  Header="Catalog" Width="100"/>
             <GridViewColumn>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                      <Button Content="Search"  Command={Binding SearchCommand}  CommandParameter="{Binding Id}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
             </GridViewColumn>

           </GridView>
    </ListView.View>
</ListView>

你的视图模型

public class MyViewModel: INotifyPropertyChanged
{
    //INotifyPropertyChanged implementation

    public ObservableCollection<MyData> MyData 
    {
        get { return _myData }
        set
        {
             _myData = value;
             OnPropertiChange(nameof(MyData));
        }
    }

    public virtual ICommand SearchCommand => new RelayCommand(o=> Search());

    private void Search()
    {
        //DoSamething

        MyData = new ObservableCollection<MyData>(ListOfMyData);
    }

}

【讨论】:

  • 当前上下文中不存在 CommandManager 的错误,SearchCommand 的名称空间不能直接包含字段等成员
  • return _canExecute?.Invoke(parameter) ?? true; 也许?它需要VS 2015+,我会更新答案
  • 看看如何在 wpf 中使用 mvvm,网上有很多例子,在 google 中搜索或在 stackoverflow 上搜索
  • 你在 RelayCommand 类中添加了引用 using System; using System.Diagnostics; using System.Windows.Input; 吗?
  • 最重要的是,如果您在项目中没有使用 MVVM,那么使用INotifyPropertyChanged 是没有用的,正如我在答案中所写的那样,您将在 ViewModel 中使用该命令,而不是在后面的代码中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 2016-03-02
  • 2016-12-06
  • 2020-10-27
  • 1970-01-01
相关资源
最近更新 更多