【问题标题】:Correct way to use a Interaction Trigger on SelectionChanged Event在 SelectionChanged 事件上使用交互触发器的正确​​方法
【发布时间】:2011-04-01 03:15:34
【问题描述】:

我有一个连接到事件的命令,它确实会触发,但我在 CommandParameter 中得到的是先前选择的项目,或者可能是在 SelectionChanged 完成之前选择的项目。

无论哪种方式,都不确定要更改什么才能从事件中获取新选择的项目。

<i:Interaction.Triggers>
  <i:EventTrigger EventName="SelectionChanged">
    <cmd:EventToCommand 
    Command="{Binding Main.SelectedRecordCommand, Source={StaticResource Locator}}" 
    CommandParameter="{Binding SelectedItem, ElementName=listBillingRecords}" 
    />
   </i:EventTrigger>
</i:Interaction.Triggers>

谢谢

【问题讨论】:

    标签: windows-phone-7 mvvm-light relaycommand eventtrigger


    【解决方案1】:

    值得使用触发器吗?如果您的集合(列表框、网格等)的任何 XAML 元素都绑定到在您的视图模型上公开集合的属性,您可以利用数据绑定和内置的 MVVM Light messenger 来通知您两者的属性更改以更 MVVM 友好的方式新旧值。这个例子不一定是特定于 WP7 的,但我认为它的工作原理是一样的。

    例如,这可能是数据绑定集合:

        public const string BillingRecordResultsPropertyName = "BillingRecordResults";
        private ObservableCollection<BillingRecord> _billingRecordResults = null;
        public ObservableCollection<BillingRecord> BillingRecordResults
        {
            get
            {
                return _billingRecordResults;
            }
    
            set
            {
                if (_billingRecordResults == value)
                {
                    return;
                }
    
                var oldValue = _billingRecordResults;
                _billingRecordResults = value;
    
                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                RaisePropertyChanged(BillingRecordResultsPropertyName, oldValue, value, true);
            }
        }
    

    我喜欢在我的 ViewModel 上公开一个属性,它是我要公开的任何集合的“选定项”。因此,对于 ViewModel,我将使用 MVVMINPC sn-p 添加此属性:

        public const string SelectedBillingRecordPropertyName = "SelectedBillingRecord";
        private BillingRecord _selectedBillingRecord = null;
        public BillingRecord SelectedBillingRecord
        {
            get
            {
                return _selectedBillingRecord;
            }
    
            set
            {
                if (_selectedBillingRecord == value)
                {
                    return;
                }
    
                var oldValue = _selectedBillingRecord;
                _selectedBillingRecord = value;
    
                // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
                RaisePropertyChanged(SelectedBillingRecordPropertyName, oldValue, value, true);
            }
        }
    

    现在,如果您将 XAML 元素的 SelectedItem 绑定到此公开的属性,它将在通过数据绑定在视图中选择时填充。

    但更好的是,当您利用 sn-p MVVMINPC 时,您可以选择是否将结果广播给任何收听的人。在这种情况下,我们想知道 SelectedBillingRecord 属性何时发生变化。因此,您可以在 ViewModel 的构造函数中使用它:

    Messenger.Default.Register<PropertyChangedMessage<BillingRecord>>(this, br => SelectedRecordChanged(br.NewValue));
    

    在您的 ViewModel 中的其他地方,无论您想采取什么行动:

        private void SelectedRecordChanged(BillingRecord br)
        {
            //Take some action here
        }
    

    希望这会有所帮助...

    【讨论】:

    • 是的..很好的答复..完全同意你所说的。我已经在我的视图模型中使用了一个可观察的集合和一个触发 raisepropchanged 的​​道具。不过有几个问题。首先,如果我对 SelectedItem 进行双向绑定,第一次传递时它为空,并且我得到一个超出范围的索引。其次,有很多方法可以更新所选项目或视图模型中的对象。在这种情况下,我只想知道它所在的列表视图何时发生更改,所以我使用了中继命令。
    • 好的,我明白你为什么现在选择使用触发器了。
    • ug... 所以我有一页,一个控件,我需要监视它在我的模型中对这个对象的更改。否则,我必须在收到更改通知的方法中做很多疯狂的事情。建议?
    • 我在视图模型上创建了第二个属性,该属性仅供列表框使用。现在...当它发生变化时,我可以更新另一个。
    • 绑定到所选项目?我曾考虑过建议第二个属性,但不确定这是否解决了双向绑定中的空项问题。此外,我永远无法确定这样的辅助属性(专门用于从视图中的一个 XAML 元素中公开某些内容)是否会破坏视图模型和视图之间的清晰区别。很高兴你有一些可行的东西!
    【解决方案2】:

    我看到了同样的问题,发现 SelectedItem 是正确的实现。

    【讨论】:

      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多