【问题标题】:Interaction Trigger before selectionChanged of ListPicker in Windows Phone 8Windows Phone 8 中 ListPicker 的 selectionChanged 之前的交互触发
【发布时间】:2013-04-20 07:51:28
【问题描述】:

当触发器出现在 ViewModel 中时,我遇到了一个问题,SelectedItem(parameter) 来自先前选择的项目。我需要新选择的项目作为 selectionChanged 的​​参数。

我是 WP8 的新手。下面是代码

    <toolkit:ListPicker Header="Background"
                                    ExpansionMode="FullscreenOnly"
                                    Template="{StaticResource ListPickerControlTemplate}"
                                    VerticalAlignment="Top"
                                    ItemsSource="{Binding Path=Buildings.ObjectList}"
                                    Margin="0"
                                    x:Name="buldings"
                                    Padding="0">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectionChanged">
                            <i:InvokeCommandAction  Command="{Binding Path=BuildingSelectionCommand}"
                                                    CommandParameter="{Binding Path=SelectedItem, ElementName=buldings}" />
                        </i:EventTrigger>
                    </i:Interaction.Triggers>

谢谢 维诺德

【问题讨论】:

    标签: xaml mvvm windows-phone-8 windows-phone eventtrigger


    【解决方案1】:

    通常您应该将当前的 SelectionItem 作为参数传递给您的命令。由于事件是用过去时写的,所以你应该得到当前的 SelectedItem 而不是以前的。

    您可以尝试将 SelectedItem 的绑定添加到您的 ListPicker,并省略将 SelectedItem 作为参数传递给您的 Command。

    <toolkit:ListPicker SelectedItem="{Binding SelectedBuilding, Mode=TwoWay}" >
      <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
          <i:InvokeCommandAction  Command="{Binding Path=BuildingSelectionCommand}"/>
        </i:EventTrigger>
      </i:Interaction.Triggers>
    </toolkit:ListPicker>
    

    然后您的命令需要访问属性 SelectedBuilding 才能执行

      public class BuildingSelectionCommand{
    
          // a reference to your ViewModel that contains the SelectedBuilding-Property
          public BuildingsViewModel ViewModel {
             get;
             set;
          }
    
          public bool CanExecute(object parameter) {
             return ViewModel.SelectedBuilding != null;
          }
    
          public void Execute(object parameter){
             var selectedItem = ViewModel.SelectedBuilding;
    
             // execute command logic with selectedItem
          }
      }
    

    您的代码可能会有所不同,因为这取决于您如何实现 ViewModel 和 Command,但我认为您应该得到它。

    另一种方法 不使用 EventTrigger,直接在 SelectedBuilding-Property 中执行命令。

    public Building SelectBuilding{
         get {
           return _selectedBuilding
         }
         set{
           _selectedBuilding = value;
           RaisePropertyChanged("SelectedBuilding");
    
           if (BuildingSelectionCommand.CanExecute(_selectedBuilding)) {
             BuildingSelectionCommand.Execute(_selectedBuilding);
           }
         }
    

    【讨论】:

    • 我没有发现 SelectedItemChanged 作为 ListPicker 的事件。我尝试了上面的代码,但没有成功。它不会被解雇。
    • @vinod8812 正确,ListPicker 只有 SelectionChanged-Event。我的错。我已经更新了我的答案以提供另一种解决方案
    • 我认为这不会起作用,因为我想执行异步方法。我无法执行异步方法。
    • @vinod8812 异步方法是什么意思。我认为您应该为您的问题添加更多详细信息
    • 异步方法不在 UI 线程上运行,即使您执行调用 web 方法等繁重操作,这也会使 UI 响应。这就是为什么在 c# 4.5 中我们将此方法用于 windows 8/phone。
    【解决方案2】:

    XAML:

    <i:EventTrigger EventName="SelectionChanged">
        <command:EventToCommand Command="{Binding BuildingSelectionCommand}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
    

    命令:

    RelayCommand<SelectionChangedEventArgs> BuildingSelectionCommand { get; set; }
    
    BuildingSelectionCommand = new RelayCommand<SelectionChangedEventArgs>(async (args) => { });
    

    您刚刚错过了“PassEventArgsToCommand”。确保您的命令具有 SelectionChangedEventArgs。

    【讨论】:

    • 阅读其他答案后,我不确定您的问题/问题是什么。
    【解决方案3】:

    解决它的简单方法是使用

    SelectedItem="{Binding SelectedBuilding, Mode=TwoWay}"
    

    正如 Jehof 建议的那样,摆脱所有“&lt;i:”触发器设置,而只需处理 SelectedBuilding 属性设置器中的更改并调用方法,而不是使用命令来包装方法调用。由于您甚至没有在此处使用CanExecute,而只是添加了更多代码,因此您不会通过命令获得任何收益。

    【讨论】:

    • 老兄,我不能使用属性更改事件来调用过于异步方法的繁重方法
    • @vinod8812 我真的不知道你的问题是什么,你现在得到了 2 个答案,而且你总是谈论你的异步方法。您的问题是,您总是将错误的项目作为参数传递给您的命令。您应该更新您的问题以提供更多信息,或者您应该回答另一个问题
    • 这里没有使用 PropertyChanged。我认为您对什么是异步方法有误解。您可以从 SelectedBuilding setter 调用异步方法,就是这样。
    • 我不喜欢这种方法。如果您的应用程序正在恢复,setter 将被击中以恢复状态。这意味着您可能正在运行仅在用户明确更改列表框时才真正想要执行的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多