我一直在尝试创建用户控件,使用此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;
}
}
答案 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
。