C# 限制listview中的列不大于X(NotifyPropertyChanged不工作)
以下是我键入数字时程序的行为方式:C# 限制listview中的列不大于X(NotifyPropertyChanged不工作),c#,wpf,data-binding,observablecollection,inotifypropertychanged,C#,Wpf,Data Binding,Observablecollection,Inotifypropertychanged,以下是我键入数字时程序的行为方式: /// <summary> /// Represent each row in listview /// </summary> public class Item : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String in
/// <summary>
/// Represent each row in listview
/// </summary>
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
void UpdateSum()
{
Sum = Col1;// + col2 + col3 etc
}
decimal _Col1;
public decimal Col1 // ||
{ // ||
get // ||
{ // ||
return _Col1; // ||
} // ||
set // ||
{ // \ || /
if (value > 100) // \ || /
{ // \/
Col1 = 100; // !!!!!!!!!!!!!!!!!!!!! HERE why does the listview does't update!!!!!!!!
NotifyPropertyChanged("Col1");
}else
{
_Col1 = value;
}
UpdateSum();
NotifyPropertyChanged("Col1");
}
}
decimal _Sum;
public decimal Sum
{
get
{
return _Sum;
}
set
{
_Sum = value;
NotifyPropertyChanged("Sum");
}
}
}
我有一个绑定到可观察集合的listview。这是我的代码:(你可以跳过这部分,类非常简单)
类项目:
/// <summary>
/// Represent each row in listview
/// </summary>
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
void UpdateSum()
{
Sum = Col1;// + col2 + col3 etc
}
decimal _Col1;
public decimal Col1 // ||
{ // ||
get // ||
{ // ||
return _Col1; // ||
} // ||
set // ||
{ // \ || /
if (value > 100) // \ || /
{ // \/
Col1 = 100; // !!!!!!!!!!!!!!!!!!!!! HERE why does the listview does't update!!!!!!!!
NotifyPropertyChanged("Col1");
}else
{
_Col1 = value;
}
UpdateSum();
NotifyPropertyChanged("Col1");
}
}
decimal _Sum;
public decimal Sum
{
get
{
return _Sum;
}
set
{
_Sum = value;
NotifyPropertyChanged("Sum");
}
}
}
//
///表示listview中的每一行
///
公共类项目:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串信息)
{
if(PropertyChanged!=null)
{
PropertyChanged(此,新PropertyChangedEventArgs(信息));
}
}
void UpdateSum()
{
Sum=Col1;//+col2+col3等
}
十进制_Col1;
公共十进制Col1//||
{ // ||
获取//||
{ // ||
返回_Col1;/| |
} // ||
设置//| |
{ // \ || /
如果(值>100)/\\\|
{ // \/
Col1=100;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!这里为什么列表视图不更新!!!!!!!!
NotifyPropertyChanged(“Col1”);
}否则
{
_Col1=值;
}
UpdateSum();
NotifyPropertyChanged(“Col1”);
}
}
十进制和;
公共十进制和
{
得到
{
返回(u)和;;
}
设置
{
_总和=价值;
通知财产变更(“金额”);
}
}
}
代码隐藏
using System;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApplication3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<Item> Collection = new ObservableCollection<Item>();
public MainWindow()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Collection.Add(new Item());
listView2.DataContext = Collection;
listView2.ItemsSource = Collection;
listView2.IsSynchronizedWithCurrentItem = true;
}
}
}
使用系统;
使用System.Windows;
使用系统组件模型;
使用System.Collections.ObjectModel;
命名空间WpfApplication3
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共ObservableCollection集合=新ObservableCollection();
公共主窗口()
{
初始化组件();
this.Loaded+=新的RoutedEventHandler(主窗口已加载);
}
已加载无效主窗口(对象发送器、路由目标)
{
集合。添加(新项());
listView2.DataContext=集合;
listView2.ItemsSource=集合;
listView2.IsSynchronizedWithCurrentItem=true;
}
}
}
xaml中的列表视图:
/// <summary>
/// Represent each row in listview
/// </summary>
public class Item : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
void UpdateSum()
{
Sum = Col1;// + col2 + col3 etc
}
decimal _Col1;
public decimal Col1 // ||
{ // ||
get // ||
{ // ||
return _Col1; // ||
} // ||
set // ||
{ // \ || /
if (value > 100) // \ || /
{ // \/
Col1 = 100; // !!!!!!!!!!!!!!!!!!!!! HERE why does the listview does't update!!!!!!!!
NotifyPropertyChanged("Col1");
}else
{
_Col1 = value;
}
UpdateSum();
NotifyPropertyChanged("Col1");
}
}
decimal _Sum;
public decimal Sum
{
get
{
return _Sum;
}
set
{
_Sum = value;
NotifyPropertyChanged("Sum");
}
}
}
无论如何,为什么当我更新
Col1=100
时,它不会在列表视图中更新!还要注意,总和是100,而不是1000。
我不希望第1列大于某个数字x。在我的实际程序中,数字是动态变化的,我在Item类中计算它
我怎样才能解决这个问题
编辑 我发现了一些有趣的东西。。。如果我开始输入不同的数字,看看会发生什么:在本例中,我将只键入5: 它在步骤3中工作!!!
一旦等于100,它就停止工作了…我让它工作了!!!我改变了:
Text="{Binding Col1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
用于:
但是我需要在文本框更改时更新属性,所以这可能是其他人的解决方案…基本上,您正在尝试在数据绑定期间更改属性值。问题是WPF试图变得聪明,不监听在数据绑定期间引发的属性更改。 这是一个众所周知的问题,有许多解决方法:
UpdateSourceTrigger=PropertyChanged
,没有一个在您的案例中起作用
然而,我可以想出一个非常肮脏的解决办法,即“工作”:
见it行动:
注意:输入第三个5后,光标将移动到文本框的开头,如果您输入下一个5,光标将保持在那里
我不认为上面提到的代码应该是解决方案,我只是玩了一点。我认为您应该使用
UpdateSourceTrigger=LostFocus
并从文本框TextChanged
事件手动进行绑定。。。但是,恐怕没有干净的解决方案来解决您的问题。基本上,文本框中存在一个错误,如果您以这种方式更改绑定值,它只会更新文本框的第一个字符。例如,如果输入1005,它会将前3个字符更新为100(但忽略5个字符)
解决这个问题很简单,我为您的Item类添加了另一个属性,并稍微更改了TextBox绑定:
public class Item : INotifyPropertyChanged
{
private int maxValue = 100;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
void UpdateSum()
{
Sum = Col1;// + col2 + col3 etc
}
decimal _Col1;
public decimal Col1
{
get
{
return _Col1;
}
set
{
if (value > maxValue)
{
Col1 = maxValue;
NotifyPropertyChanged("Col1");
}
else
{
_Col1 = value;
}
UpdateSum();
NotifyPropertyChanged("Col1");
}
}
public int MaxValueWidth
{
get
{
var tmp = (int)Math.Log10(maxValue) + 1;
return tmp;
}
}
decimal _Sum;
public decimal Sum
{
get
{
return _Sum;
}
set
{
_Sum = value;
NotifyPropertyChanged("Sum");
}
}
}
请注意,我添加了一个属性,该属性根据最大值计算文本框的最大字符数
不,我所做的就是添加绑定
<DataTemplate>
<TextBox Width="200" Text="{Binding Col1, UpdateSourceTrigger=PropertyChanged}" MaxLength="{Binding MaxValueWidth}"></TextBox>
</DataTemplate>
您不应该将属性更改两次,最后的一次就足够了。这对您没有什么帮助,但是在您的Col1设置程序中,将if(value>100){Col1=100;..
更改为if(value>100){Col1=100;..
我应该包装//HACK:根据条件取消bindig if(value>100)抛出n