UserControl不显示绑定的集合

时间:2017-07-28 18:49:26

标签: c# wpf xaml user-controls

我一直在尝试创建用户控件,使用此article作为我的开始。 我的最终结果是提供一个集合并使用TextBox过滤集合,在ListView中显示过滤后的结果。

问题是,我的绑定似乎没有正常工作。该集合未被传递到UserControl。请记住,这是我创建UserControl的第一步。为什么会这样?

  

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

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

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(调用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

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;
    }
}

1 个答案:

答案 0 :(得分:2)

您正在分配

listView.ItemsSource = AllItems;
SearchList构造函数中的

。稍后,在MainWindow构造函数中,执行

slist.AllItems = items;

现在,您似乎认为listView.ItemsSource神奇地拥有对您的MainWindow的items集合的引用。事实并非如此。

使用数据绑定而不是直接赋值。在SearchList XAML中,写下:

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

并从SearchList构造函数中删除listView.ItemsSource = AllItems