5

以下是我键入数字时程序的行为方式:

在此处输入图像描述

我有一个绑定到可观察集合的列表视图。这是我的代码:(你可以跳过这部分,类很简单)

班级项目:

/// <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");
        }
    }
}

代码背后

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;
        }
    }
}

xaml 中的列表视图:

 <ListView Name="listView2" >
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Column1" Width="200">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="200" Text="{Binding Col1, UpdateSourceTrigger=PropertyChanged}"></TextBox>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Sum" Width="200">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Width="200" Text="{Binding Sum, UpdateSourceTrigger=PropertyChanged}"></TextBox>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

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

无论如何,为什么当我更新Col1=100它不会在列表视图中更新!还要注意总和是如何变成 100 而不是 1000 的。

我不希望 column1 大于某个数字 x。在我的真实程序中,这个数字是动态变化的,我在 Item 类中计算它。

我怎样才能解决这个问题?



编辑

我发现了一些有趣的东西......如果我开始输入不同的数字,看看会发生什么:在这个例子中我只输入 5:

在此处输入图像描述

它在第 3 步有效!!!

一旦它等于 100,它就会停止工作......

4

3 回答 3

1

我成功了!!!我变了:

 Text="{Binding Col1, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"

为了:

 Text="{Binding Col1, Mode=TwoWay}"

但是我需要在文本框更改时更新属性,所以这可能是其他人的解决方案......

于 2012-04-16T01:36:22.927 回答
1

基本上,您试图在 DataBinding 期间更改属性值。问题是 WPF 试图变得聪明,而不是监听 DataBinding 期间引发的属性更改。这是一个众所周知的问题,有许多解决方法:

尽管 MS 在 WPF4.0 中做了一些修复,请参阅:WPF 4.0 Data Binding Change (great feature)

但是我做了一些快速测试,但由于UpdateSourceTrigger=PropertyChanged.

但是我可以想出一个“有效”的非常肮脏的解决方法:

public decimal Col1
{
    get { return _Col1; }
    set
    {
        //Change the property value based on condition
        _Col1 = value > 100 ? 100 : value;
        UpdateSum();
        //HACK: Simulate that the property change not fired from the setter
        Dispatcher.CurrentDispatcher
            .BeginInvoke(new Action(() => NotifyPropertyChanged("Col1")));
        //HACK: Cancel the bindig based on condition
        if (value > 100)
            throw new Exception();
    }
}

看它动作:

在此处输入图像描述

注意:在输入第三个 5 后,光标会移动 TextBox 的开头,如果您输入下一个 5,它会保留在那里。

我不认为上面提到的代码应该是解决方案,我只是玩了一下。我认为您应该UpdateSourceTrigger=LostFocus从文本框事件中手动进行绑定TextChanged...但是恐怕您的问题没有干净的解决方案。

于 2012-04-23T05:53:10.160 回答
0

基本上,TextBox 中存在一个错误,如果您以这种方式更改绑定值,它只会更新 TextBox 的第一个字符。例如,如果您输入 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");
        }
    }
}

请注意,我添加了一个属性,该属性根据最大值计算 TextBox 的最大字符数。

不,我所做的只是添加绑定

<DataTemplate>
    <TextBox Width="200" Text="{Binding Col1, UpdateSourceTrigger=PropertyChanged}" MaxLength="{Binding MaxValueWidth}"></TextBox>
</DataTemplate>
于 2012-04-25T12:32:51.540 回答