Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以最优雅的方式将数据绑定到ItemsControl中的特定项属性?_C#_.net_Wpf_Silverlight - Fatal编程技术网

C# 如何以最优雅的方式将数据绑定到ItemsControl中的特定项属性?

C# 如何以最优雅的方式将数据绑定到ItemsControl中的特定项属性?,c#,.net,wpf,silverlight,C#,.net,Wpf,Silverlight,场景:一个列表视图被数据绑定到一个可观察集合,并通过一个自定义项目模板显示它的项目。CustomClass只包含三个字符串属性和一个布尔属性,并且已经在它的四个属性中的每一个上实现了inotifypropertychange。ListView的自定义ItemTemplate对三个字符串属性具有单向绑定,对boolean属性具有双向绑定,并将其显示为复选框 问题:我正在寻找一种最优雅的方式(就WPF而言)来显示该列表视图中使用文本块的所有选中项的计数,或者换句话说,在该集合中,所有布尔属性设置为t

场景:一个列表视图被数据绑定到一个
可观察集合
,并通过一个自定义项目模板显示它的项目。
CustomClass
只包含三个字符串属性和一个布尔属性,并且已经在它的四个属性中的每一个上实现了inotifypropertychange。ListView的自定义ItemTemplate对三个字符串属性具有单向绑定,对boolean属性具有双向绑定,并将其显示为复选框

问题:我正在寻找一种最优雅的方式(就WPF而言)来显示该列表视图中使用文本块的所有选中项的计数,或者换句话说,在该集合中,所有布尔属性设置为
true
的项。如果某个ListView项目被选中/取消选中,我希望该文本块立即更新显示的计数。我知道有(相当)丑陋的方法通过代码隐藏和事件处理来实现这一点,但我想知道是否有一种聪明的方法可以完全用XAML和神秘的数据绑定语法来实现这一点


编辑:正如示例/说明:ListView显示100个项目,90个项目的布尔属性设置为
true
,因此TextBlock将显示“90”。如果用户通过复选框取消选中另一个项目,并因此通过双向绑定将其属性设置为
false
,则文本块应更新为“89”。

如果它是一个简单的ASP.NET表单,我将考虑使用JQuery对列表框中的选定项目进行计数。在WPF中,这可能仍然是一个可行的选择:

var count = 0;
$('#multiItemListBox :selected').each(count++);

将此代码插入ListBox的OnChange事件的JS事件处理程序。您必须知道在客户端得到的HTML中实际会调用什么样的列表框,我不确定WPF是如何将它们混合在一起的,或者如何将正确的引用粘贴到服务器端XAML中。

您可以使用转换器构建一个包含选中项计数的字符串

public sealed class CountToStringConverter : System.Windows.Data.IValueConverter {
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        ObservableCollection<CustomClass> items = value as ObservableCollection<CustomClass>;

        int count = 0;

        foreach (var item in items) {
            if (item.IsChecked) {
                count++;
            }
        }

        return count + " Items";
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        throw new NotImplementedException();
    }

    #endregion
}
公共密封类CountToString转换器:System.Windows.Data.IValueConverter{
#区域转换器成员
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性){
ObservableCollection项目=作为ObservableCollection的价值;
整数计数=0;
foreach(项目中的var项目){
如果(项目已检查){
计数++;
}
}
返回计数+项目数;
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性){
抛出新的NotImplementedException();
}
#端区
}
将TextBox的Text属性绑定到集合

<TextBox Text={Binding Items, Converter={StaticResource countToStringConverter}}/>

更新:
仅当属性项触发PropertyChanged事件(如果集合已更改)时,此绑定才起作用。

我个人可能会在我的ViewModel中执行此操作。订阅ObservaleCollection中的项上更改的属性,然后在布尔属性更改时向ViewModel上更改的Count属性发送信号。在您看来,只需绑定到Count属性。

感谢我得到的所有答案,这些都是适用的解决方案,但不幸的是,这并不是我想要实现的。这就是我现在解决问题的方法:

我在包含TextBlock的窗口上实现了DependencyProperty:

public static readonly DependencyProperty ActiveItemCountProperty =
        DependencyProperty.Register("ActiveItemCount", typeof(int), typeof(CustomControl), new UIPropertyMetadata(0));
在ListView项目的DataTemplate上,复选框为Click事件注册了EventHandler:

<CheckBox IsChecked="{Binding Active, Mode=TwoWay}" Click="CheckBox_Click" />

代码隐藏中的事件处理程序如下所示:

    private void CheckBox_Click(object sender, RoutedEventArgs e)
    {
        ObservableCollection<CustomClass> sourceCol = listView.DataContext as ObservableCollection<CustomClass>;
        if (sourceCol != null)
            ActiveItemCount = sourceCol.Count(x => x.Active);
    }
private void复选框\单击(对象发送者,路由目标)
{
ObservableCollection sourceCol=listView.DataContext作为ObservableCollection;
if(sourceCol!=null)
ActiveItemCount=sourceCol.Count(x=>x.Active);
}
显然,TextBlock只是绑定到此DependencyProperty的数据:

<TextBlock Text="{Binding Path=ActiveItemCount, ElementName=ControlRoot}" />


ControlRoot是窗口的名称。

谢谢您的回答,但我不只是想显示所选项目的计数(我可以简单地绑定到SelectedItems.count),而是要显示将特定属性(在本例中为布尔属性)设置为特定值的所有项目的计数。例如:ListView有100个项目,其中90个项目的布尔属性设置为true-因此TextBlock将显示“90”。如果我取消选中一个项目,它会显示89个,但是ListView本身仍然有所有100个初始项目。谢谢你的回答。的确,扩展ViewModel是一种很好的方法。但我有点想避免这种情况,因为我使用的是非常简单的数据结构。。。我一直在考虑在DataTemplate上实现一个EventSetter,以从代码隐藏中处理每个项的复选框的选中事件。。。但我真正想做的是对ListView的ItemsSource或ObjectDataProvider进行某种直接数据绑定,它利用LINQ语句或类似的东西…@naacal。提供一个包含检查项计数的附加属性比使用EventSetter、checked Event等更容易。@Jehof:这可能确实很容易,但我必须实现另一个类,以便为我提供此属性。现在,CustomClass并不打算成为ViewModel的一部分,这也是我最初问题的全部目的——是否有任何方法可以在XAML中做到这一点,而无需实现更多代码,只需将这个小数据绑定到TextBlock。主/详细实现中的数据绑定语法使用特殊斜杠(/)语法绑定到当前项,这让我想到,可能有一种方法可以在ItemsSource和bool属性上执行类似的操作