如何在每次更改时动态显示ListBox中的项目数?

时间:2014-07-25 18:58:30

标签: c# events listbox

我有一个C#项目,它有一个ListBox作为其用户界面的一部分。此ListBox用于显示许多项目名称。我还有一些选项可以根据对数据库的查询(所有项目,不完整,完整等)更改此ListBox的大小。

我还有一个标签,显示ListBox内的结果数量。我希望每次列表更改时都能找到一种自动执行此操作的方法,而不是在我更改列表的每行代码中。

我尝试过使用DataSourceChanged事件,但这会带来一个非常有趣的问题。在实际使用新值填充ListBox之前触发事件。例如,在程序开始时,我将ListBox的数据源设置为一组100个项目。然后,触发DataSourceChanged事件,我调用listBox1.Items.Count.ToString()来获取值,然后返回0.再次,因为列表框尚未填充。所以我将有一个显示0的标签和一个包含100个项目的列表框。

现在,如果我将其缩小到不完整的项目(例如,计数为50),当事件被触发时,它将返回值100.这是因为不完整的项目没有'自数据源发生变化以来,人口已经填充。所以,我会有一个标签,上面写着100,但只有50个项目的列表框。

我还可以使用其他活动吗? DataSourceChanged事件是否具有可以查看待处理数据源以获取计数的任何参数?或者我应该在代码中找到更改列表框并更新标签的每个实例。

1 个答案:

答案 0 :(得分:1)

您可以使用接口ICollectionView执行此类任务,这甚至可以使您的项目源保持不变(保存您的数据库一些工作量,以及很多混乱)。 您还需要在此处的其他注释中使用您的itemssource的ObservableCollection。您应该使用绑定,命令和工作,而不是关注WPF中的事件。令人讨厌的代码隐藏给老MVVM老将眼睛疼痛并让小猫咪哭泣;)

尽可能使用过滤器,完全更改"数据源"你只需更改Stuffs集合。请原谅我的命名,我试图让你的例子尽可能简单。

的Xaml:

<Window x:Class="custtest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:custtest="clr-namespace:custtest"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <custtest:MainViewModel/>
    </Window.DataContext>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="Auto" MinWidth="100"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource="{Binding Stuffs}" Grid.Row="0" Grid.Column="0"></ListBox>
        <TextBlock  Grid.Row="0" Grid.Column="1" Text="{Binding StuffFilterView.Count}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
        <TextBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"  Text="{Binding SearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></TextBox>
    </Grid>
</Window>

视图模型:

以下代码非常简单,你永远不应该在ctor中做我做的事情!这只是为了简单起见。

public class MainViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> stuffs;
    private string searchText;
    private ICollectionView stuffFilterView;

    public ICollectionView StuffFilterView
    {
        get { return stuffFilterView; }
        set
        {
            if (Equals(value, stuffFilterView)) return;
            stuffFilterView = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<String> Stuffs
    {
        get { return stuffs; }
        set
        {
            if (Equals(value, stuffs)) return;
            stuffs = value;
            OnPropertyChanged();
        }
    }

    public String SearchText
    {
        get { return searchText; }
        set
        {
            if (value == searchText) return;
            searchText = value;
            OnPropertyChanged();
            OnSearchTextChanged();
        }
    }

    private void OnSearchTextChanged()
    {
        StuffFilterView.Refresh(); // Refresheses content in your ICollectionView when text changes            
    }

    public MainViewModel()
    {
        // Bad pie!
        Stuffs = new ObservableCollection<string> {"jall", "b", "c", "d", "blabla"};
        StuffFilterView = CollectionViewSource.GetDefaultView(Stuffs);
        StuffFilterView.Filter = FilterStuff;
    }

    private bool FilterStuff(object obj)
    {
        String str = obj.ToString();
        if (String.IsNullOrEmpty(SearchText))
            return true;

        return str.Contains(SearchText);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator] // R# remove if you don't have it
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

希望它有所帮助!

干杯, 了Stian