dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
6.94k stars 1.15k forks source link

UpdateSourceTrigger=PropertyChanged #9356

Open vsfeedback opened 3 weeks ago

vsfeedback commented 3 weeks ago

This issue has been moved from a ticket on Developer Community.


After the data is bound, set UpdateSourceTrigger=PropertyChanged, and no decimal point can be entered. This is the case with both the bound DATa Grid and the bound Text Box. This issue should have been there in 2019.


Original Comments

Alison Jin [MSFT] on 6/25/2024, 01:03 PM:

(private comment, text removed)

正堃 黄 on 6/26/2024, 08:00 PM:

(private comment, text removed)

正堃 黄 on 7/1/2024, 02:16 PM:

(private comment, text removed)

正堃 黄 on 7/2/2024, 09:12 AM:

(private comment, text removed)

Feedback Bot on 6/27/2024, 08:17 AM:

(private comment, text removed)

Ann Yang [MSFT] on 6/27/2024, 11:53 AM:

(private comment, text removed)

Feedback Bot on 7/2/2024, 11:34 AM:

(private comment, text removed)

正堃 黄 on 7/4/2024, 07:27 AM:

(private comment, text removed)


Original Solutions

(no solutions)


Repro

PropertyIssue.zip

miloush commented 3 weeks ago

Well you have a double backing storage which cannot store the difference between 2 2. and 2.0 and 2.0e+0 and 2.000000 etc. You have two way binding on property changed, so any text change will be converted to double and then read back again (in case the value was coerced) and converted back to string.

You have couple of options: a. Do not have property changed trigger on numeric values, especially floating ones. I would strongly encourage that option, as the values you would be getting will jump wildly as typed. Also note you can enter "NaN", "∞" etc. b. Remember somewhere the resulting double value and do not update the textbox if it's the same. This could be done either in a converter, a control inheriting from TextBox, or by not using a binding, at least not two-way one.

sykn0811 commented 3 weeks ago

这个明显是个BUG!为什么UpdateSourceTrigger=LostFocus可以,而UpdateSourceTrigger=PropertyChanged就不可以? 只要第一个字符不是数字,后面可以随便输入任何字符,如果第一位是数字,后面就不能输入”."了。 我需要Mode=TwoWay,这跟数据类型无关,即使是float和decimal也不行。 当然我可以用UpdateSourceTrigger=LostFocus,然后在做其他处理。 我英文不好,只能用汉字了,抱歉!

miloush commented 3 weeks ago

Because with LostFocus, the value is converted to double only after you have typed the whole thing. Trying to implement the binding yourself using the text changed event might give you some insight on how this works and what the issues are.

sykn0811 commented 3 weeks ago

可是我只想用UpdateSourceTrigger=PropertyChanged,不想用yoUpdateSourceTrigger=LostFocus。

miloush commented 3 weeks ago

Then you have to do extra work and store the string somewhere.

sykn0811 commented 3 weeks ago

我只想知道在WPF的DataGrid中,绑定UpdateSourceTrigger=PropertyChanged的情况下,能否用键盘输入小数点?这个是不是bug? 我不想继续讨论下去了,我可以用UpdateSourceTrigger=LostFocus,无非是多写几行代码而已!

miloush commented 3 weeks ago

It is not a bug, I tried to explain why it works this way. You can create a string property in your data model (or better a view model) and bind to it instead, for example:

class BgData : INotifyPropertyChanged
{
    ...
    private double _pt;
    private string _ptString;

    public double Pt
    {
        get { return _pt; }
        set
        {
            if (value != _pt)
            {
                _pt = value;
                _ptString = null;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Pt)));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PtString)));
            }
        }
    }
    public string PtString
    {
        get { return _ptString ?? _pt.ToString("G17"); }
        set
        {
            if (value != _ptString)
            {
                if (double.TryParse(value, out double pt))
                    Pt = pt;

                _ptString = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PtString)));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
lindexi commented 3 weeks ago

@sykn0811 Please don't get angry here. @miloush is right.


@sykn0811 不要在这里带着情绪哦, @miloush 说的是对的。如果你真想这么用,再定义一个中间数据层

sykn0811 commented 3 weeks ago

既然都说不是bug,肯定不是bug了。 这个属性值如果能够输入小数点,那就更好了

sykn0811 commented 2 weeks ago

DataGrid还有些疑问:

  1. UpdateSourceTrigger=LostFocus时,按下Enter键后焦点已经变化,但是绑定的源没用变化。
  2. 其中网格线有三种,列头网格线,内部网格线和外框线。各线的默认线宽不一致,位置不同,重叠后很不美观。
  3. RowHeaderWidth只是在第一列的前面留下一定的空白,还有什么作用?
lindexi commented 2 weeks ago

@sykn0811

  1. 先用 snoop 工具定位一下,确定是否焦点变化了
  2. 这个可以改改样式解决,但是可能默认的行为不好改,说不定有开发者已经以来这些行为了
sykn0811 commented 2 weeks ago

焦点是否发生变化,我不太确定。但是按下回车键以后,下面的单元格变成了蓝色。