2017-07-28 8 views
1

私はこのarticleを私のスタートとして使用してユーザーコントロールを作成しようとしています。 私の最終的な結果は、コレクションを提供し、TextBoxを使用してコレクションをフィルタリングし、フィルタリングされた結果をListViewに表示することです。UserControlはバインディングからコレクションを表示しません

問題は、私のバインディングが正しく機能していないようです。コレクションは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)); 
    } 

} 
<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.csCollection.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(作成されたユーザーコントロールを呼び出しウィンドウ)

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

答えて

2

あなたはSEARCHLISTコンストラクタで

listView.ItemsSource = AllItems; 

を割り当てています。その後、メインウィンドウのコンストラクタで、あなたは

slist.AllItems = items; 

今、あなたはlistView.ItemsSource魔法自分のメインウィンドウのitemsコレクションへの参照を保持しているという印象の下にあるように見えるん。そうではありません。

直接割り当ての代わりに、データバインディングを使用します。 SEARCHLIST XAMLでは、このように書きます:

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

とSEARCHLISTコンストラクタからlistView.ItemsSource = AllItemsを削除します。

関連する問題