简体   繁体   English

UserControl不显示绑定中的集合

[英]UserControl doesnt display collection from binding

I've been trying to create a user control, using this article as my start. 我一直在尝试使用本文作为创建用户控件的起点。 My end result would be supplying a collection and using the TextBox to filter the collection, displaying the filtered result in the ListView . 我的最终结果将是提供一个集合,并使用TextBox过滤该集合,在ListView显示过滤的结果。

Problem is, it seems that my binding isn't working correctly. 问题是,看来我的装订工作不正确。 The collection isn't being passed through to the UserControl . 集合没有传递给UserControl Bear in mind, this is my first shot at creating a UserControl . 请记住,这是我创建UserControl第一步。 Why would this happen? 为什么会这样?

SearchList.Xaml SearchList.Xaml

<UserControl x:Class="CreatingControls.SearchList"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:CreatingControls"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" Loaded="SearchList_OnLoaded">


<StackPanel>
    <TextBox Name="txtFilter"
             TextChanged="txtFilter_TextChanged"
             Margin="5" FontSize="20" />

    <TextBox IsEnabled="False" Text="Search:"
             FontSize="16" BorderThickness="0" />

    <ListView Name="listView"
              SelectedValue="{Binding Path=SelectedItem}"
              DisplayMemberPath="Value"
              BorderBrush="LightGray" Margin="5" />
</StackPanel>

SearchList.xaml.cs SearchList.xaml.cs

public partial class SearchList : UserControl
{
    #region AllItems

    public List<Collection> AllItems
    {
        get { return (List<Collection>)GetValue(AllItemsProperty); }
        set { SetValue(AllItemsProperty, value); }
    }

    public static readonly DependencyProperty AllItemsProperty =
        DependencyProperty.Register("AllItems", typeof(List<Collection>),
          typeof(SearchList), new PropertyMetadata(default(List<Collection>)));

    #endregion

    #region SelectedItem

    public Collection SelectedItem
    {
        get { return (Collection)GetValue(SelectedItemProperty); }
        set { SetValue(SelectedItemProperty, value); }
    }

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register("SelectedItem", typeof(Collection),
          typeof(SearchList), new PropertyMetadata(default(Collection)));

    #endregion

    public SearchList()
    {
        InitializeComponent();

        listView.ItemsSource = AllItems;

        if (listView.ItemsSource != null)
        {
            CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(listView.ItemsSource);
            view.Filter = ItemsFilter;
        }
    }

    private void SearchList_OnLoaded(object sender, RoutedEventArgs e)
    {
        if (listView.ItemsSource == null)
            return;

        CollectionViewSource.GetDefaultView(listView.ItemsSource).Filter = ItemsFilter;
    }

    private void txtFilter_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (listView.ItemsSource == null)
            return;

        CollectionViewSource.GetDefaultView(listView.ItemsSource).Refresh();
    }

    private bool ItemsFilter(object item)
    {
        if (listView.ItemsSource == null)
            return false;

        if (String.IsNullOrEmpty(txtFilter.Text))
            return true;

        var collectionItem = (Collection)item;

        return (collectionItem.Value.StartsWith(txtFilter.Text, StringComparison.OrdinalIgnoreCase) || collectionItem.Value.StartsWith(txtFilter.Text, StringComparison.OrdinalIgnoreCase));
    }

}

Collection.cs Collection.cs

public class Collection : INotifyPropertyChanged
{
    private string _id;
    public string Id
    {
        get { return _id; }
        set { SetField(ref _id, value, "Id"); }
    }

    private string _value;
    public string Value
    {
        get { return _value; }
        set { SetField(ref _value, value, "Value"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

MainWindow.xaml (Window that calls the UserControl created) MainWindow.xaml(创建UserControl的窗口)

<Window x:Class="CreatingControls.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:uControls="clr-namespace:CreatingControls"
    mc:Ignorable="d"
    d:DataContext="Models."
    Title="MainWindow" >

<Grid>
    <uControls:SearchList x:Name="slist" />
</Grid>

MainWindow.xaml.cs MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public static List<Collection> items { get; set; }
    public User SelectedUser { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        items = new List<Collection>();
        items.Add(new Collection { Id = "1", Value = "A" });
        items.Add(new Collection { Id = "2", Value = "B" });
        items.Add(new Collection { Id = "3", Value = "C" });
        items.Add(new Collection { Id = "4", Value = "D" });
        items.Add(new Collection { Id = "5", Value = "E" });
        items.Add(new Collection { Id = "6", Value = "F" });
        items.Add(new Collection { Id = "7", Value = "G" });
        items.Add(new Collection { Id = "8", Value = "H" });

        slist.AllItems = items;
    }
}

You are assigning 您正在分配

listView.ItemsSource = AllItems;

in the SearchList constructor. 在SearchList构造函数中。 Later, in the MainWindow constructor, you do 稍后,在MainWindow构造函数中

slist.AllItems = items;

Now you seem to be under the impression that listView.ItemsSource magically holds a reference to the items collection of your MainWindow. 现在,您似乎对listView.ItemsSource神奇地拥有对MainWindow的items集合的引用有一种印象。 That is not the case. 事实并非如此。

Instead of the direct assignment, use data binding. 代替直接分配,而使用数据绑定。 In the SearchList XAML, write this: 在SearchList XAML中,编写以下代码:

<ListView ItemsSource="{Binding AllItems,
                        RelativeSource={RelativeSource AncestorType=UserControl}}" .../>

and remove listView.ItemsSource = AllItems from the SearchList constructor. 并从SearchList构造函数中删除listView.ItemsSource = AllItems

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM