【问题标题】:ListView does not update with PropertyChanged EventListView 不随 PropertyChanged 事件更新
【发布时间】:2018-04-18 23:32:08
【问题描述】:

我正在使用 This Design Pattern for MVVM 开发 WPF 应用程序

我有以下 XML

<TextBox Text="{Binding SelectedLimitAmount, UpdateSourceTrigger=PropertyChanged, StringFormat={}{0:$#,#.00}}"
        Grid.Column="1" Grid.Row="0" Height="20" Margin="2,2,2,2"/>
<Button Content="Adjust" 
        FontSize="9"
        Command="{Binding AdjustLimit}"
        Background="Blue" Foreground="White"
        Grid.Column="1" Grid.Row="1" 
        Height="20" Width="75" HorizontalAlignment="Right" Margin="2,2,2,2"/>
<!--Credit Limit Listview-->
<ListView ItemsSource="{Binding Limits, UpdateSourceTrigger=PropertyChanged}" 
          SelectedItem="{Binding SelectedLimit}"
          SelectionMode="Single"
          Grid.ColumnSpan="2" Grid.Row="2" Margin="2,2,2,0">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Account" DisplayMemberBinding="{Binding Activity}"/>
            <GridViewColumn Header="Credit Limit" DisplayMemberBinding="{Binding LimitAmount, StringFormat={}{0:$#,#.00}}"/>
        </GridView>
    </ListView.View>
</ListView>

绑定到这段代码:

Public Class ImportPresenter : ObservableObject
{
    //Credit Limits
    private ObservableCollection<CreditLimitItem> _Limits;
    private CreditLimitItem _SelectedLimit;
    private decimal _SelectedLimitAmount = 0;

    public ObservableCollection<CreditLimitItem> Limits
    {
        get
        {
            return _Limits;
        }
        set
        {
            _Limits = value;
            Debug.Print("Limits Updated");
            RaisePropertyChangedEvent("Limits");
        }
    }

    public decimal SelectedLimitAmount
    {
        get { return _SelectedLimitAmount; }
        set
        {
            _SelectedLimitAmount = value;
            Debug.Print("Amount Changed");
            RaisePropertyChangedEvent("SelectedLimitAmount");
        }
    }

    /// <summary>
    /// Selected Credit Limit
    /// </summary>
    public CreditLimitItem SelectedLimit
    {
        get
        {
            return _SelectedLimit;
        }
        set
        {
            _SelectedLimit = value;
            SelectedLimitAmount = _SelectedLimit.LimitAmount;
            RaisePropertyChangedEvent("SelectedLimit");
        }
    }

    public ICommand AdjustLimit
    {
        get { return new DelegateCommand(UpdateLimit); }
    }

    private void UpdateLimit()
    {
        if(_SelectedLimit != null)
        {
            _SelectedLimit.LimitAmount = _SelectedLimitAmount;
            RaisePropertyChangedEvent("Limits");

            foreach(CreditLimitItem item in Limits)
            {
                Debug.Print(item.LimitAmount.ToString());
            }
        }
    }
}

public class CreditLimitItem
{

    private int _LimitSequence;
    private short _ActivitySequence;
    private string _Activity;
    private decimal _LimitAmount;
    private DateTime _StartDate;
    private DateTime _EndDate;
    private decimal _NewLimit;

    public int LimitSequence { get => _LimitSequence; set => _LimitSequence = value; }
    public short ActivitySequence { get => _ActivitySequence; set => _ActivitySequence = value; }
    public string Activity { get => _Activity; set => _Activity = value; }
    public decimal LimitAmount { get => _LimitAmount; set => _LimitAmount = value; }
    public DateTime StartDate { get => _StartDate; set => _StartDate = value; }
    public DateTime EndDate { get => _EndDate; set => _EndDate = value; }
    public decimal NewLimit { get => _NewLimit; set => _NewLimit = value; }
    public decimal LimitChange { get => _LimitAmount - _NewLimit; }


    public CreditLimitItem(int sequence, short activitySequence, string activity, decimal amount, DateTime startDate, DateTime endDate)
    {
        _LimitSequence = sequence;
        _ActivitySequence = activitySequence;
        _Activity = activity;
        _LimitAmount = amount;
        _StartDate = startDate;
        _EndDate = endDate;
    }
}

但是,当我更新 TextBox 控件时,ListView 不会在 PropertyChanged 事件上刷​​新。我的 XAML 中是否缺少某些内容?我应该能够在我的TextBox 中调整选定的CreditLimitItem.LimitAmount,并且在我单击Adjust 后相关的ListView 应该会更新。不过不知道为什么它不起作用。

【问题讨论】:

  • CreditLimitItem 必须是 ObservableObject 并且您需要在绑定值上引发属性更改
  • 请注意,在 ItemsSource Binding 上设置 UpdateSourceTrigger=PropertyChanged 是没有意义的。这里没有任何作用,与INotifyPropertyChanged接口的PropertyChanged事件无关。
  • 您必须为 CreditLimitItem.LimitAmout 属性触发 PropertyChanged 事件。这不会自动发生。
  • 只有当它应该通知值变化时:-)
  • 轻微批评,ObservableCollections 应该是只读属性。他们有 UI 使用的更改通知。这就是为什么它们是“可观察的”。

标签: c# wpf xaml mvvm


【解决方案1】:

您的类 CreditLimitItem 应该为此实现 INotifyPropertyChanged。 当您调用 _SelectedLimit.LimitAmount = _SelectedLimitAmount; 时,没有任何事情发生,因为 LimitAmount 设置器不会引发 PropertyChanged 事件。请注意,RaisePropertyChangedEvent("Limits"); 根本没有效果,因为 Limits 仍然是同一个集合。

【讨论】:

  • 谢谢!我曾假设在Limits 属性中触发PropertyChanged 事件会改变集合。我已经在CreditLimitItem 类中调整了我的属性来实现它,它现在可以工作了。谢谢!
猜你喜欢
  • 2013-04-25
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 2011-02-05
  • 2022-09-28
  • 1970-01-01
  • 2011-12-23
  • 2021-11-27
相关资源
最近更新 更多