Limit column in list view to more than X (NotifyPropertyChanged does not work)

This is how my program behaves as you enter numbers:

enter image description here

I have a list attached to an observable collection. Here is my code: (you can skip this part, the classes are very simple)

Grade:

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

Code for

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

List in 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>

In any case, when I update Col1=100, it is not updated in the list! Also note how the amount is 100, not 1000.

I do not want column1 to be greater than some number x. In my real program, this number changes dynamically, and I compute it inside the Item class.

How can i fix this?



Edit

I found something interesting ... If I start typing in different taks numbers, see what happens: I just type 5 in this example:

enter image description here

It works in step 3 !!!

100, ...

+5
3

! :

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

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

, - ...

+1

DataBinding. , WPF , DataBinding. :

MS WPF4.0, . : WPF 4.0 ( )

, - 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();
    }
}

:

enter image description here

: 5 TextBox , 5.

, , . , UpdateSourceTrigger=LostFocus TextChanged ... , .

+1

There is basically an error in a TextBox, where if you change the value of the binding in this way, it only updates the first characters of the TextBox. For example, if you entered 1005, it updates the first 3 characters to 100 (but ignores 5).

The fix is ​​simple, Ive added another property of the Item class to you and slightly changed the binding of the 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");
        }
    }
}

Note that Ive added a property that calculates the maximum characters for the TextBox base at the maximum value.

No, all I do is add a binding

<DataTemplate>
    <TextBox Width="200" Text="{Binding Col1, UpdateSourceTrigger=PropertyChanged}" MaxLength="{Binding MaxValueWidth}"></TextBox>
</DataTemplate>
0
source

All Articles