WPF搜索框和数据绑定到treeview

时间:2009-06-02 14:23:41

标签: c# wpf data-binding

我正在尝试实现一个实时更新搜索栏,当搜索词组发生变化时会更新TreeView,但是我并没有设法让它以我想要的方式更新。

应用程序启动时,所有项目都存在于树视图中(目前只包含一个级别的子项)。当我在文本框中键入并调用PropertyChanged事件时,SearchPhrase属性也正确更新,但是不调用Items get。我的猜测是它与表示模型Items属性有关。我是对的吗?

这是我的XAML:

<Border BorderBrush="Black">
        <TextBox VerticalAlignment="Top" x:Name="phrase" Text="{ Binding      Path=SearchPhrase, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }" Height="24" />
    </Border>
    <TreeView  Height="200" Background="Gainsboro" Name="list" ItemsSource="{ Binding Path=Items, Mode=OneWay, UpdateSourceTrigger=PropertyChanged }" ItemTemplate="{StaticResource dataTemplate}" />

这是我的演示模型:

public class ProjectListPM : BasePM
{
    private List<AnalysisInfo> items;
    private String searchPhrase;

    /// <summary>
    /// Gets or sets the search phrase.
    /// </summary>
    public String SearchPhrase { 
        get
        {
            return this.searchPhrase;
        }
        set
        {
            if (value != null)
            {
                this.searchPhrase = value;
                FirePropertyChanged<ProjectListPM>(o => o.SearchPhrase);
            }
        }
    }

    /// <summary>
    /// The list of analysises to display in the list.
    /// </summary>
    public List<AnalysisInfo> Items { 
        get
        {
            return
                items.OrderByDescending(i => i.GetSearchRelevanceTo(SearchPhrase)).Where(
                    i => i.GetSearchRelevanceTo(SearchPhrase) > 0).ToList();
        }
        set
        {
            if (value != null)
            {
                this.items = value;
                FirePropertyChanged<ProjectListPM>(o => o.Items);
            }
        }
    }

    public ProjectListPM()
    {
        this.items = new List<AnalysisInfo>();
        this.SearchPhrase = String.Empty;
    }
}

public class BasePM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Called when a property is changed.       
    /// </summary>
    /// <typeparam name="T">Type</typeparam>
    /// <param name="exp">Function</param>
    protected void FirePropertyChanged<T>(Expression<Func<T, Object>> exp)
    {
        string propertyName;
        if (exp.Body is UnaryExpression)
            propertyName = ((MemberExpression)((UnaryExpression)exp.Body).Operand).Member.Name;
        else
            propertyName = ((MemberExpression)exp.Body).Member.Name;
        if (PropertyChanged != null)
        {
            //Switch to UI thread
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

2 个答案:

答案 0 :(得分:1)

看起来您想根据搜索词组过滤树视图的项目集合。

作为即时解决方案,您可以在SearchPhrase设置器中添加一行:

set
{
    if (value != null)
    {
        this.searchPhrase = value;
        FirePropertyChanged<ProjectListPM>(o => o.SearchPhrase);
        FirePropertyChanged<ProjectListPM>(0 => o.Items);
    }
}

这会在您设置SearchPhrase的任何时候通知UI刷新项目。

如果您想要采用不同的方法,可以从ItemsControl扩展BasePM,在构造函数中设置ItemsSource和Items.Filter属性,并在设置SearchPhrase时调用Items.Refresh()。

答案 1 :(得分:0)

您的List类是WPF可以使用的吗?我建议使用System.Collections.ObjectModel.ObservableCollection,因为它已经实现了与WPF兼容的列表更改事件。