C# MVVM按钮内容属性不工作
我有这个密码C# MVVM按钮内容属性不工作,c#,wpf,mvvm,data-binding,C#,Wpf,Mvvm,Data Binding,我有这个密码 private string _contentButtonDisplaySearch; public string ChangeContentButtonDisplaySearch { get { return _contentButtonDisplaySearch; } set { if (_contentButtonDisplaySearch == value) return; _contentB
private string _contentButtonDisplaySearch;
public string ChangeContentButtonDisplaySearch
{
get { return _contentButtonDisplaySearch; }
set
{
if (_contentButtonDisplaySearch == value)
return;
_contentButtonDisplaySearch = value;
OnPropertyChanged();
}
}
InotifyProperty已更改
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
我设置了DataContext,但这不起作用
<Button x:Name="ButtonDisplaySearch" Content="{Binding ChangeContentButtonDisplaySearch}" DataContext="{Binding}" HorizontalAlignment="Left" Margin="188,0,0,10" VerticalAlignment="Bottom" Width="164" Height="39"/>
当有加载主窗口时,当我设置_contentButtonDisplaySearch时,按钮内容会更改,但当我尝试更改时,什么也不会发生直接修改属性而不是它的值。如果修改变量
set
将不会被触发,并且OnPropertyChange()代码>事件将不会被激发
尝试通过属性直接赋值:
private void OKRun()
{
ChangeContentButtonDisplaySearch = "ChangeContent";
}
xaml
中的
应该设置UpdateSourceTrigger
属性:
<Button Content="{Binding ChangeContentButtonDisplaySearch, UpdateSourceTrigger=PropertyChanged}"/>
直接修改属性而不是其值。如果修改变量set
将不会被触发,并且OnPropertyChange()代码>事件将不会被激发
尝试通过属性直接赋值:
private void OKRun()
{
ChangeContentButtonDisplaySearch = "ChangeContent";
}
xaml
中的
应该设置UpdateSourceTrigger
属性:
<Button Content="{Binding ChangeContentButtonDisplaySearch, UpdateSourceTrigger=PropertyChanged}"/>
我真的很感兴趣,为什么按钮
控件的内容
属性实际上没有更新。我已经找到了原因。原因string
类型是不可变的,如果条件if(\u contentButtondDisplaySearch!=value)
不合适,因为我们刚刚有了新的string
对象,这个新创建的string
对象将始终等于属性的值:
您的视图模型:
public class YourViewModel:ViewModelBase
{
int _contentButtonDisplaySearch = 1;
public string ChangeContentButtonDisplaySearch
{
get { return _contentButtonDisplaySearch; }
set
{
//if(_contentButtonDisplaySearch!= value)//this condition is not appropriate
//cause we have just new `string` object and this newly created
//`string` object will be always equal to the `value` of property
_contentButtonDisplaySearch = value;
OnPropertyChanged("ChangeContentButtonDisplaySearch");
}
}
private ICommand _changeCountCommand;
public ICommand ChangeCountCommand
{
get
{
if (_changeCountCommand == null)
{
_changeCountCommand = new RelayCommand(
p => ChangeViewModel(),
p => true);
}
return _changeCountCommand;
}
}
private void ChangeViewModel()
{
ChangeContentButtonDisplaySearch++;
}
}
ViewModelBase类:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
您的xaml:
<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:YourViewModel/>
</Window.DataContext>
<StackPanel>
<Button Content="{Binding ChangeContentButtonDisplaySearch}" Command="{Binding ChangeCountCommand}"></Button>
<TextBlock Text="{Binding ChangeContentButtonDisplaySearch}"/>
</StackPanel>
</Window>
我真的很感兴趣,为什么按钮
控件的内容
属性实际上没有更新。我已经找到了原因。原因string
类型是不可变的,如果条件if(\u contentButtondDisplaySearch!=value)
不合适,因为我们刚刚有了新的string
对象,这个新创建的string
对象将始终等于属性的值:
您的视图模型:
public class YourViewModel:ViewModelBase
{
int _contentButtonDisplaySearch = 1;
public string ChangeContentButtonDisplaySearch
{
get { return _contentButtonDisplaySearch; }
set
{
//if(_contentButtonDisplaySearch!= value)//this condition is not appropriate
//cause we have just new `string` object and this newly created
//`string` object will be always equal to the `value` of property
_contentButtonDisplaySearch = value;
OnPropertyChanged("ChangeContentButtonDisplaySearch");
}
}
private ICommand _changeCountCommand;
public ICommand ChangeCountCommand
{
get
{
if (_changeCountCommand == null)
{
_changeCountCommand = new RelayCommand(
p => ChangeViewModel(),
p => true);
}
return _changeCountCommand;
}
}
private void ChangeViewModel()
{
ChangeContentButtonDisplaySearch++;
}
}
ViewModelBase类:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
您的xaml:
<Window x:Class="SampleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleApplication"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:YourViewModel/>
</Window.DataContext>
<StackPanel>
<Button Content="{Binding ChangeContentButtonDisplaySearch}" Command="{Binding ChangeCountCommand}"></Button>
<TextBlock Text="{Binding ChangeContentButtonDisplaySearch}"/>
</StackPanel>
</Window>
我的看法
public partial class MainWindow : IView
{
public MainWindow()
{
InitializeComponent();
}
public void ShowIView()
{
this.Show();
}
public void ShowViewAsModal()
{
this.ShowDialog();
}
public void SetDataContext(object dataContext)
{
this.DataContext = dataContext;
}
伊维
视图模型
public class PriceListViewModels<TViewType> : IViewModel where TViewType : IView, new ()
{
private readonly IView _view;
private readonly PriceListModel _modelPriceListModel;
private readonly PriceModel _modelPriceModel;
private readonly NewServInPriceListModel _modelNewServInPriceListModel;
public ObservableCollection<PriceList> PriceListObservableCollection { get; set; }
public ObservableCollection<Price> PriceObservableCollection { get; set; }
public ObservableCollection<NewServInPriceList> NewServObServableCollection { get; set; }
public RelayCommand CommandSave { get; private set; }
// создаем объект ICollection View, для отображения и фильтрации данных в Datagrid
public ICollectionView collview { get; private set; }
public ObservableCollection<bool> Colec { get; set; }
#region fields
private string _textBoxSearch; // переменная которая связана с TextBoxSearch во View
private DateTime _dateTimeBeginPriceList;
private DateTime _dateTimeEndPriceList;
private int _selectedIndexListBox;
private string _textBoxComment;
private string _contentButtonDisplaySearch;
// переменные для выбора типов оплаты
private bool _omsIsChecked;
private bool _dmsIsChecked;
private bool _budshetIsChecked;
private bool _platnoIsChecked;
private bool _displayRadioButton;
private bool _searchRadionButton;
#endregion
#region Constructors
public PriceListViewModels()
{
this._view = new TViewType();
this._modelPriceListModel = new PriceListModel();
this.PriceListObservableCollection = new ObservableCollection<PriceList>(this._modelPriceListModel.GetService());
this._modelPriceModel = new PriceModel();
this.PriceObservableCollection = new ObservableCollection<Price>(this._modelPriceModel.GetPrice());
this._modelNewServInPriceListModel = new NewServInPriceListModel();
this.NewServObServableCollection = new ObservableCollection<NewServInPriceList>(this._modelNewServInPriceListModel.GetNewServ());
this.CommandSave = new RelayCommand(o => this.OKRun());
// присваиваем collview observable collection
collview = (CollectionView)CollectionViewSource.GetDefaultView(NewServObServableCollection);
// задаем начальные значения для DateTimePicker
_dateTimeBeginPriceList = DateTime.Today.AddDays(-1);
_dateTimeEndPriceList = new DateTime(2016, 05, 28);
_displayRadioButton = true;
_contentButtonDisplaySearch = "Найти";
this._view.SetDataContext(this);
this._view.ShowIView();
}
public类PriceListViewModels:IViewModel其中TViewType:IView,new()
{
私有只读IView\u视图;
private readonly PriceListModel\u model PriceListModel;
私有只读PriceModel\u modelPriceModel;
私有只读NewServicePriceListModel\u ModelNewServicePriceListModel;
公共ObservableCollection价格列表ObservableCollection{get;set;}
公共ObservableCollection价格ObservableCollection{get;set;}
公共ObservableCollection NewserveObservableCollection{get;set;}
public RelayCommand CommandSave{get;private set;}
//ICollection视图、数据网格
公共ICollectionView collview{get;private set;}
公共可观察集合集合{get;set;}
#区域字段
私有字符串textBoxSearch;//查看
private DateTime\u dateTimeBeginPriceList;
private DateTime_dateTimeEndPriceList;
私有int_selectedIndexListBox;
私有字符串_textBoxComment;
私有字符串_contentButtonDisplaySearch;
// переменные для выбора типов оплаты
对私人住宅进行检查;
对私人住宅进行检查;
私人住宅区;
私人布卢广场;
专用布尔显示单选按钮;
私人广播按钮;
#端区
#区域构造函数
公共价格列表视图模型()
{
这是。_view=new TViewType();
这是._modelPriceListModel=新的PriceListModel();
this.PriceListObservableCollection=新的ObservableCollection(this.\u modelPriceListModel.GetService());
这是。_modelPriceModel=新的PriceModel();
this.PriceObservableCollection=新的ObservableCollection(this.\u modelPriceModel.GetPrice());
这是._modelNewServicenPriceListModel=新的NewServicenPriceListModel();
this.newserveobservecollection=新的observecollection(this._modelnewservicenpricelistmodel.GetNewServ());
this.CommandSave=newrelaycommand(o=>this.OKRun());
//ПаааМcollview可观测集合
collview=(CollectionView)CollectionViewSource.GetDefaultView(NewServeObservableCollection);
//日期时间选择器
_dateTimeBeginPriceList=DateTime.Today.AddDays(-1);
_dateTimeEndPriceList=新的日期时间(2016,05,28);
_displayRadioButton=true;
_contentButtonDisplaySearch=“аааааа”;
this.\u view.SetDataContext(this);
这是。_view.ShowIView();
}
我调试我的代码,执行程序,它不会改变每个属性ContentButtonDisplaySearch我的视图
private void OKRun()
{
_contentButtonDisplaySearch = "ChangeContent";
}
public partial class MainWindow : IView
{
public MainWindow()
{
InitializeComponent();
}
public void ShowIView()
{
this.Show();
}
public void ShowViewAsModal()
{
this.ShowDialog();
}
public void SetDataContext(object dataContext)
{
this.DataContext = dataContext;
}
伊维
视图模型
public class PriceListViewModels<TViewType> : IViewModel where TViewType : IView, new ()
{
private readonly IView _view;
private readonly PriceListModel _modelPriceListModel;
private readonly PriceModel _modelPriceModel;
private readonly NewServInPriceListModel _modelNewServInPriceListModel;
public ObservableCollection<PriceList> PriceListObservableCollection { get; set; }
public ObservableCollection<Price> PriceObservableCollection { get; set; }
public ObservableCollection<NewServInPriceList> NewServObServableCollection { get; set; }
public RelayCommand CommandSave { get; private set; }
// создаем объект ICollection View, для отображения и фильтрации данных в Datagrid
public ICollectionView collview { get; private set; }
public ObservableCollection<bool> Colec { get; set; }
#region fields
private string _textBoxSearch; // переменная которая связана с TextBoxSearch во View
private DateTime _dateTimeBeginPriceList;
private DateTime _dateTimeEndPriceList;
private int _selectedIndexListBox;
private string _textBoxComment;
private string _contentButtonDisplaySearch;
// переменные для выбора типов оплаты
private bool _omsIsChecked;
private bool _dmsIsChecked;
private bool _budshetIsChecked;
private bool _platnoIsChecked;
private bool _displayRadioButton;
private bool _searchRadionButton;
#endregion
#region Constructors
public PriceListViewModels()
{
this._view = new TViewType();
this._modelPriceListModel = new PriceListModel();
this.PriceListObservableCollection = new ObservableCollection<PriceList>(this._modelPriceListModel.GetService());
this._modelPriceModel = new PriceModel();
this.PriceObservableCollection = new ObservableCollection<Price>(this._modelPriceModel.GetPrice());
this._modelNewServInPriceListModel = new NewServInPriceListModel();
this.NewServObServableCollection = new ObservableCollection<NewServInPriceList>(this._modelNewServInPriceListModel.GetNewServ());
this.CommandSave = new RelayCommand(o => this.OKRun());
// присваиваем collview observable collection
collview = (CollectionView)CollectionViewSource.GetDefaultView(NewServObServableCollection);
// задаем начальные значения для DateTimePicker
_dateTimeBeginPriceList = DateTime.Today.AddDays(-1);
_dateTimeEndPriceList = new DateTime(2016, 05, 28);
_displayRadioButton = true;
_contentButtonDisplaySearch = "Найти";
this._view.SetDataContext(this);
this._view.ShowIView();
}
public类PriceListViewModels:IViewModel其中TViewType:IView,new()
{
私有只读IView\u视图;
private readonly PriceListModel\u model PriceListModel;
私有只读PriceModel\u modelPriceModel;
私有只读NewServicePriceListModel\u ModelNewServicePriceListModel;
公共ObservableCollection价格列表ObservableCollection{get;set;}
公共ObservableCollection价格ObservableCollection{get;set;}
公共ObservableCollection NewserveObservableCollection{get;set;}
public RelayCommand CommandSave{get;private set;}
//ICollection视图、数据网格
公共ICollectionView collview{get;private set;}
公开收集
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Learn.MVVM.Example.ViewModels
{
public interface IViewModel
{
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Learn.MVVM.Example.Common.Commands;
using Learn.MVVM.Example.Models;
using Learn.MVVM.Example.Models.Business;
using Learn.MVVM.Example.Views;
namespace Learn.MVVM.Example.ViewModels
{
public class PersonsViewModel<TViewType> : IViewModel where TViewType : IView, new()
{
private readonly IView _view;
private readonly PersonModel _model;
public ObservableCollection<Person> Persons { get; set; }
public RelayCommand OkCommand { get; private set; }
private string _str;
public PersonsViewModel()
{
this._view = new TViewType();
this._model = new PersonModel();
this.Persons = new ObservableCollection<Person>(this._model.GetPersons());
this.OkCommand = new RelayCommand(o => this.OKRun());
_str = "Кнопка";
this._view.SetDataContext(this);
this._view.ShowView();
}
public string Str
{
get { return _str; }
set
{
if (_str == value)
return;
_str = value;
OnPropertyChanged("Str");
}
}
public event PropertyChangedEventHandler PropertyChanged;
//[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private void OKRun()
{
_str = "Change";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Learn.MVVM.Example.Views
{
public interface IView
{
void ShowView();
void ShowViewAsModal();
void SetDataContext(object dataContext);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Learn.MVVM.Example.Views
{
/// <summary>
/// Логика взаимодействия для PersonsView.xaml
/// </summary>
public partial class PersonsView: IView
{
public PersonsView()
{
InitializeComponent();
}
public void ShowView()
{
this.Show();
}
public void ShowViewAsModal()
{
this.ShowDialog();
}
public void SetDataContext(object dataContext)
{
this.DataContext = dataContext;
}
}
}
<Window x:Class="Learn.MVVM.Example.Views.PersonsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PersonsView" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<DataGrid ItemsSource="{Binding Persons}" />
<Button Content="{Binding Str, UpdateSourceTrigger=PropertyChanged}" DataContext="{Binding Str}" Name="OKButton" Command="{Binding OkCommand}" Grid.Row="1"/>
</Grid>
</Window>
using System;
using System.Windows.Input;
namespace Learn.MVVM.Example.Common.Commands
{
public class RelayCommand : ICommand
{
private Predicate<object> canExecute;
private Action<object> execute;
public RelayCommand(Action<object> execute) : this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
CanExecuteChangedInternal -= value;
}
}
public bool CanExecute(object parameter)
{
return canExecute != null && canExecute(parameter);
}
public void Execute(object parameter)
{
execute(parameter);
}
private event EventHandler CanExecuteChangedInternal;
public void OnCanExecuteChanged()
{
var handler = CanExecuteChangedInternal;
if (handler != null)
{
handler.Invoke(this, EventArgs.Empty);
}
}
public void Destroy()
{
canExecute = _ => false;
execute = _ => { };
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
}
public class PriceListViewModels<TViewType> : **INotifyPropertyChanged**, IViewModel where TViewType : IView, new ()