带有复选框的ListView

时间:2011-11-04 15:09:07

标签: wpf events binding mvvm checkbox

我有一个显示为ListBox的项目列表。

<ListView ItemsSource="{Binding ListOfSomeItems}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Status">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox IsChecked="{Binding IsReceived}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

现在我需要实现2个用户案例:

1)当用户将项目标记为已接收时(CheckBox被选中)我需要更新该项目。我应该如何将已检查的事件绑定到我的ViewModel中的ICommand?

2)当用户试图删除收到的标志(取消选中复选框)时,应该提供一个弹出窗口,其中包含取消操作的选项(如果有人意外点击了复选框)或者提供了一个说明原因。该注释以及未经检查的项目应发送到VM中的不同ICommand。

有什么建议吗?

提前致谢

更新 我的viewModel实现了INoftiyPropertyChanged但我没有单项的属性。该属性嵌套在复杂的类中:类似于Account.Holders [x] .Requirements [y] .IsReceived。

4 个答案:

答案 0 :(得分:0)

您的ViewModel应该实现INoftiyPropertyChanged。只需听取PropertyChanged事件并对其做出回应。

修改

根据ViewModel的结构,如果Account需要响应需求,最好使用Prism的EventAggregator或MVVM Light的Messenger。

答案 1 :(得分:0)

  1. 为什么不绑定应由ViewModel公开的命令:
  2. <CheckBox 
         Command="{Binding ReceivedStatusChangedCommand}"
         CommandParameter="{Binding ...IsReceived}"
    />
    

    然后在命令处理程序中,您可以分析IsReceived的传入值作为命令参数。

答案 2 :(得分:0)

由于您绑定到对象中的IsChecked属性,因此您只需监听该对象的PropertyChanged事件,并在更改时调用所需的任何方法。

例如,

// Wireup CollectionChanged in Constructor
public MyVMConstructor()
{
    ListOfSomeItems = new List<SomeItem>();
    ListOfSomeItems.CollectionChanged += ListOfSomeItems_CollectionChanged;
}

// In CollectionChanged event, wire up PropertyChanged event on items
void ListOfSomeItems_CollectionChanged(object sender, CollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach(SomeItem item in e.NewItems)
            item.PropertyChanged += SomeItem_PropertyChanged;
    }
    if (e.OldItems != null)
    {
        foreach(SomeItem item in e.OldItems)
            item.PropertyChanged -= SomeItem_PropertyChanged;
    }
}

// In PropertyChanged, if property was IsReceived then verify and update
void SomeItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "IsReceived")
    {
        if (MessageBox.Show("Are you sure?", "Confirm", MessageBoxButtons.YesNo) == DialogResult.Yes)
        {
            var item = sender as SomeItem;
            UpdateSomeItem(item.Id, item.IsReceived);
        }
    }
}

答案 3 :(得分:-1)

MVVM解决方案将是:

  1. 由于绑定是两种方式,因此您无需执行任何操作即可从UI更新对象。但是,如果您希望更新模型中的更改,则模型类需要实现INotifyPropertyChanged
  2. 我想这可以在IsReceived setter中完成。在模型类中添加两个字段。

  3. public string ValidationError
    { get; set; }
    
    public bool HasValidationError
    { get; set; }
    

    然后创建一个默认隐藏的错误PopUp。在您的类中实施INotifyPropertyChanged,并将PopUp可见性绑定到HasValidationError,并将内部TextBlock中的消息绑定到ValidationError