【问题标题】:How to access a control from ICommand Execute() in ViewModel?如何从 ViewModel 中的 ICommand Execute() 访问控件?
【发布时间】:2014-04-18 18:25:37
【问题描述】:

我正在尝试使用 ICommand 接口实现我的第一个 wpf 项目。当用户单击重置按钮时,我想取消选择列表框中的所有项目。但我不知道如何从 viewmodel 中的 ICommand 访问列表框。我正在为 ICommand 使用 DelegateCommand 模式。它显示消息,但无法访问 AbsenseCodeListbox。那么这样做的方法是什么?谢谢。

    <Button Content="Reset"  Grid.Column="2" Margin="0,10,20,5" Command="{Binding AbsenceResetCommand}"/>
...

    <ListBox Name="AbsenseCodeListbox" ItemsSource="{Binding absenseCodeItems, Mode=OneWay}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="5" Margin="20,0,20,5" >
    </ListBox>

我的视图模型中的代码:

void AbsenceResetCommand_Execute(object arg)
{
    MessageBox.Show("_AbsenceResetCommand command");
    AbsenseCodeListbox.UnselectAll();//Can't do this way

}

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    通常,您的视图模型对象具有 ObservableCollection 类型的公共属性,您可以将其数据绑定到 XAML 中的 ListBox 控件的 ItemsSource 属性。

    您可以做的是向视图模型添加另一个名为SelectedItems 的属性,它也是ObservalbeCollection。您可以使用 2 路绑定将此属性绑定到 ListBox' SelectedItems 属性。然后,要清除 ListBox 中的选定项,您只需清除 SelectedItems 集合:

    void AbsenceResetCommand_Execute(object arg)
    {
        SelectedItems.Clear(();
    }
    

    【讨论】:

    • 这不会取消选择项目...它会将它们从列表框中删除。
    • 你是对的。我更改了答案以添加另一个绑定到可以清除的 ListBox's SelectedItems 属性的属性。
    【解决方案2】:

    您不想访问该控件。您应该将 ListBoxItem 的 IsSelected 属性绑定到您的缺席代码项上的 IsSelected 属性(如果这样做更有意义,请添加此属性或创建一个包装类)。然后,您只需在 ViewModel 中引用缺席代码项并将其 IsSelected 属性设置为 false。

    XAML:

    <ListBox Name="AbsenseCodeListbox" ItemsSource="{Binding absenseCodeItems, Mode=OneWay}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="5" Margin="20,0,20,5" >
       <ListBox.ItemContainerStyle>
          <Style TargetType="{x:Type ListBoxItem}">
             <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
          </Style>
       </ListBox.ItemContainerStyle>
    </ListBox>
    

    命令:

    void AbsenceResetCommand_Execute(object arg)
    {
       MessageBox.Show("_AbsenceResetCommand command");
       Foreach (var absenseCodeItem in absenseCodeItems)
          absenseCodeItem.IsSelected = false;
    }
    

    由于 UI 虚拟化,您会在选择同步方面遇到一些问题,因此这里有一些链接指向一个 3 部分系列,展示了更完整的实现:Part 1Part 2Part 3

    【讨论】:

    • 感谢您以这种方式告知。
    【解决方案3】:

    你必须像这样在命令参数中传递列表框

     <Button CommandParameter="{Binding ElementName=AbsenseCodeListbox}" Content="Reset"  Grid.Column="2" Margin="0,10,20,5" Command="{Binding AbsenceResetCommand}"/>
     <ListBox Name="AbsenseCodeListbox" ItemsSource="{Binding absenseCodeItems, Mode=OneWay}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="5" Margin="20,0,20,5" >
     </ListBox>
    

    视图模型将变为

       void AbsenceResetCommand_Execute(object arg)
        {
            ListBox tempListBox = arg as ListBox;
    
            if (tempListBox != null)
                tempListBox.UnselectAll();
        }
    

    【讨论】:

    • 感谢您告诉我。
    猜你喜欢
    • 2015-07-21
    • 2010-12-11
    • 1970-01-01
    • 2012-02-24
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    相关资源
    最近更新 更多