Gil*_*zzi 9 wpf user-controls mvvm
我有一个带有ItemsSource属性的UserControl.由于基本UserControl类没有实现ItemsSource,我必须创建自己的依赖属性,如下所示:
#region ItemsSource Dependency Property
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(MonthViewControl),
new PropertyMetadata(OnItemsSourceChanged));
static void OnItemsSourceChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
(obj as MonthViewControl).OnItemsSourceChanged(e);
}
private void OnItemsSourceChanged(DependencyPropertyChangedEventArgs e)
{
RefreshLayout();
}
public IEnumerable ItemsSource
{
get
{
return (base.GetValue(ItemsSourceProperty) as IEnumerable);
}
set
{
base.SetValue(ItemsSourceProperty, value);
}
}
#endregion
Run Code Online (Sandbox Code Playgroud)
现在在我的ViewModel中,我有一个Events属性,它是EventItem项的ICollectionView,如下所示:
private ObservableCollection<Controls.EventCalendar.EventItem> eventItems;
private CollectionViewSource events;
public System.ComponentModel.ICollectionView Events
{
get
{
if (events == null)
{
events = new CollectionViewSource();
events.Source = eventItems;
}
return events.View;
}
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题是,在我的View中,当我绑定到Events属性,并且我将一个Item添加到eventItems时,UserControl将不会触发ItemsSourceChanged事件,因此不会更新UI.为了测试,我在视图中添加了一个简单的列表框,它也绑定到Events属性.这就像一个魅力.eventItems observableCollection的更新反映在ListBox中.
我认为它与我的ItemsSource依赖属性有关.也许我需要使用继承FormControl而不是UserControl的自定义控件?
为了帮助您了解我的问题:我正在尝试创建一个类似控件的日历,用于显示事件/议程条目(类似于Google日历).它就像一个魅力.调整控件大小时更新UI.唯一剩下的就是ItemsSource更改后的自动更新.
希望有人能提供帮助.
编辑:我发布的那一刻我意识到事件无法触发,因为ItemsSource属性不会更改.它是基础集合的变化.但是,我不是那样处理的.我需要实现什么才能使其工作.只是暗示就足够了.我不需要每个实现细节.
在Reflector中打开PresentationFramework.dll并查看System.Windows.Controls.ItemsControl,显示以下内容:
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable),
typeof(ItemsControl), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(ItemsControl.OnItemsSourceChanged)));
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ItemsControl control = (ItemsControl) d;
IEnumerable oldValue = (IEnumerable) e.OldValue;
IEnumerable newValue = (IEnumerable) e.NewValue;
ItemValueStorageField.ClearValue(d);
if ((e.NewValue == null) && !BindingOperations.IsDataBound(d, ItemsSourceProperty))
{
control.Items.ClearItemsSource();
}
else
{
control.Items.SetItemsSource(newValue);
}
control.OnItemsSourceChanged(oldValue, newValue);
}
Run Code Online (Sandbox Code Playgroud)
不知道RefreshLayout我的预感是什么,它与ObservableCollection<T>被包装的方式有关,因为上面的代码不知道具体的集合类型是什么,因此它将被包装的类型处理; 在这种情况下,ObservableCollection<T>尝试修改您的属性,如下所示返回默认视图并调整您的ItemsSource属性,使其更类似于框架中的上述代码,并从那里向后工作.
private ObservableCollection<Controls.EventCalendar.EventItem> eventItems;
private ICollectionview eventsView;
public System.ComponentModel.ICollectionView Events
{
get
{
if (eventsView == null)
eventsView = CollectionViewSource.GetDefaultView(eventItems);
return eventsView;
}
}
Run Code Online (Sandbox Code Playgroud)