1

在 Listbox 中,我有带有复选框的项目,在 TextBlock 中,我想更新计数器,显示当前检查了多少。简单的场景,但我在刷新计数器绑定时遇到问题。

我的xml:

<Window x:Class="ListboxWithCounting.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:ListboxWithCounting"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:MyViewModel />
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate x:Key="CheckBoxListItem">
            <Border x:Name="CheckBoxItemElement" 
                    Background="Transparent" 
                    Padding="0,2,0,2">
                <CheckBox Content="{Binding Name}" 
                          IsChecked="{Binding Path=IsChecked,Mode=TwoWay,
                    UpdateSourceTrigger=PropertyChanged}"/>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBlock Grid.Column="1">
            <TextBlock.Text>
                <MultiBinding StringFormat="Items checked: {0} of {1}">
                    <Binding Path="ColumnsChecked" />
                    <Binding Path="ColumnsCount" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>

        <ListBox ItemTemplate="{StaticResource CheckBoxListItem}" 
                         x:Name="Columns" 
                         ItemsSource="{Binding Columns}" />
    </Grid>
</Window>

我的视图模型和单个项目:

public class Item : INotifyPropertyChanged
    {
        public string Name { set; get; }

        private bool isChecked;
        public bool IsChecked
        {
            get
            {
                return isChecked;
            }
            set
            {
                isChecked = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    }

    public class MyViewModel
    {
        public int ColumnsCount
        {
            get
            {
                return Columns.Count;
            }
        }

        public int ColumnsChecked
        {
            get
            {
                return Columns.Where(x => x.IsChecked).Count();
            }
        }

        public List<Item> Columns
        {
            get
            {
                var data = new List<Item>()
                {
                    new Item(){ Name = "Item1", IsChecked=true },
                    new Item(){ Name = "Item2" },
                    new Item(){ Name = "Item3" }
                };

                data.ForEach(x => x.PropertyChanged += (s, e) => { });

                return data;
            }
        }
    }

当列表状态上的每个复选框都更改时,如何触发多重绑定?

[更新]

感谢 slugster,工作代码:

public class Item : INotifyPropertyChanged
    {
        public string Name { set; get; }

        private bool isChecked;
        public bool IsChecked
        {
            get
            {
                return isChecked;
            }
            set
            {
                if (isChecked != value)
                {
                    isChecked = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    }

    public class MyViewModel : INotifyPropertyChanged
    {
        public int ColumnsCount
        {
            get
            {
                return Columns.Count;
            }
        }

        public int ColumnsChecked
        {
            get
            {
                return Columns.Where(x => x.IsChecked).Count();
            }
        }

        private List<Item> columns;
        public List<Item> Columns
        {
            get
            {
                if (columns == null)
                {
                    columns = new List<Item>()
                    {
                        new Item(){ Name = "Item1", IsChecked=true },
                        new Item(){ Name = "Item2" },
                        new Item(){ Name = "Item3" }
                    };
                }

                columns.ForEach(x =>
                {
                    x.PropertyChanged -= x_PropertyChanged;
                    x.PropertyChanged += x_PropertyChanged;
                });

                return columns;
            }
        }

        void x_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            PropertyChanged(this, new PropertyChangedEventArgs("ColumnsChecked"));
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    }
4

1 回答 1

2

您的视图模型还需要实现INotifyPropertyChanged,以便可以使绑定知道列表项上的属性更改。

老实说,我无法告诉您仅通知一个属性是否会导致评估整个多重绑定(无论如何您都可以快速找出),但是您可能希望通知中的两个属性任何其他绑定的情况。

public class MyViewModel : INotifyPropertyChanged
{

    [...snip...]

    public List<Item> Columns
    {
        get
        {
            var data = new List<Item>()
            {
                new Item(){ Name = "Item1", IsChecked=true },
                new Item(){ Name = "Item2" },
                new Item(){ Name = "Item3" }
            };

            data.ForEach(x => x.PropertyChanged += (s, e) => {       
                                                                OnPropertyChanged("ColumnsCount");
                                                                OnPropertyChanged("ColumnsChecked");
                                                             });

            return data;
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

}
于 2013-10-07T07:42:39.143 回答