gpt4 book ai didi

wpf - 具有自定义 ItemsSource 依赖属性的用户控件

转载 作者:行者123 更新时间:2023-12-04 04:19:17 26 4
gpt4 key购买 nike

我有一个带有 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

现在在我的 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;
}
}

我面临的问题是,在我的 View 中,当我绑定(bind)到 Events 属性并将 Item 添加到 eventItems 时,UserControl 不会触发 ItemsSourceChanged 事件,因此不会更新 UI。
为了测试,我在 View 中添加了一个简单的列表框,该列表框也绑定(bind)到 Events 属性。这就像一个魅力。对 eventItems observableCollection 的更新反射(reflect)在 ListBox 中。

我认为它与我的 ItemsSource 依赖属性有关。也许我需要使用继承表单 ItemsControl 而不是 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);
}

不知道是什么 RefreshLayout我的预感是它与 ObservableCollection<T> 的方式有关吗?正在被包装,因为上面的代码不知 Prop 体的集合类型是什么,因此它将由被包装的类型处理;在这种情况下是 ObservableCollection<T>尝试如下修改您的属性以返回默认 View 并调整您的 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;
}
}

关于wpf - 具有自定义 ItemsSource 依赖属性的用户控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4539416/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com