![](/img/trans.png)
[英]How to bind dependency property to DataGridComboBoxColumn in UserControl?
[英]How to bind collection dependency property in UserControl
這不是重復的! 當我失敗時,我嘗試尋找類似的帖子,但沒有成功。 我不明白為什么未調用OnUCItemsSourceChanged
? 我很確定我錯過了一些簡單的事情,但是找不到。
我有一個包含UserControl1
Window
,該Window
具有附加的集合屬性,該屬性綁定到Window
的WindowCollection
集合。 我希望在向WindowCollection
添加項目時調用UserControl1.OnUCItemsSourceChanged
。 但這不會發生。
我想念什么?
Window1.xaml.cs
public partial class Window1 : Window
{
public ObservableCollection<long> WindowCollection { get; set; }
public Window1()
{
InitializeComponent();
DataContext = this;
WindowCollection = new ObservableCollection<long>();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
WindowCollection.Add(1);
WindowCollection.Add(2);
}
}
Window1.xaml
<StackPanel>
<uc:UserControl1 UCItemsSource="{Binding Path=WindowCollection}" />
<Button Content="Refresh" Click="Button_Click" />
</StackPanel>
UserControl1.xaml.cs
public static readonly DependencyProperty UCItemsSourceProperty = DependencyProperty.Register("UCItemsSource", typeof(IEnumerable), typeof(UserControl1), new PropertyMetadata(null, new PropertyChangedCallback(OnUCItemsSourceChanged)));
public IEnumerable UCItemsSource
{
get { return (IEnumerable)GetValue(UCItemsSourceProperty ); }
set { SetValue(UCItemsSourceProperty , value); }
}
public ObservableCollection<MyItem> UCItems { get; set; }
private static void OnUCItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as UserControl1;
var items = e.NewValue as ObservableCollection<long>;
foreach (var item in items)
{
control.UCItems.Add(new MyItem(item));
}
}
UserControl1.xaml
<ItemsControl ItemsSource="{Binding UCItems}" ... />
更新這是我的測試項目的鏈接
在這一行:
<ItemsControl ItemsSource="{Binding UCItems}" ... />
必須是帶有FindAncestor的RelativeSource
,因為UCItems
位於UserControl中:
UserControl
<ItemsControl ItemsSource="{Binding Path=UCItems,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" />
I cannot understand why OnUCItemsSourceChanged is not called?
如果添加RelativeSource構造,則OnUCItemsSourceChanged
至少OnUCItemsSourceChanged
引起一次,因為PropertyChangedCallback
每次都會觸發,因此您需要為依賴項屬性設置新值:
表示當依賴項屬性的有效屬性值更改時調用的回調。
由於您曾經在此處設置依賴項屬性的值:
<uc:UserControl1 UCItemsSource="{Binding Path=WindowCollection}" />
I expect UserControl1.OnUCItemsSourceChanged to be called when I add items to WindowCollection.
為此,存在一個ObservableCollection<T>.CollectionChanged
事件,其中包含對集合執行的動作的枚舉:
在添加,刪除,更改,移動項目或刷新整個列表時發生。
對於您的情況將是這樣的:
Version with CollectionChanged
MainWindow
public partial class MainWindow : Window
{
public ObservableCollection<long> WindowCollection { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
WindowCollection = new ObservableCollection<long>();
WindowCollection.Add(1);
WindowCollection.Add(2);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
WindowCollection.Add(3);
WindowCollection.Add(4);
}
}
UserControl
public partial class UserControl1 : UserControl
{
#region Public Section
public ObservableCollection<long> UCItems { get; set; }
public static UserControl1 control;
#endregion
public UserControl1()
{
InitializeComponent();
UCItems = new ObservableCollection<long>();
}
#region UCItemsSource Property
public static readonly DependencyProperty UCItemsSourceProperty = DependencyProperty.Register("UCItemsSource",
typeof(IEnumerable),
typeof(UserControl1),
new PropertyMetadata(null, new PropertyChangedCallback(OnUCItemsSourceChanged)));
public IEnumerable UCItemsSource
{
get { return (IEnumerable)GetValue(UCItemsSourceProperty); }
set { SetValue(UCItemsSourceProperty, value); }
}
#endregion
private static void OnUCItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
control = d as UserControl1;
var items = e.NewValue as ObservableCollection<long>;
items.CollectionChanged += new NotifyCollectionChangedEventHandler(CollectionChanged);
AddItem(control, items);
}
private static void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
var items = sender as ObservableCollection<long>;
control.UCItems.Clear();
if (e.Action == NotifyCollectionChangedAction.Add)
{
AddItem(control, items);
}
}
private static void AddItem(UserControl1 userControl, ObservableCollection<long> collection)
{
if (collection.Count > 0)
{
foreach (var item in collection)
{
userControl.UCItems.Add(item);
}
}
}
}
該項目在此
link
可用
Alternative version
此版本更簡單,更正確。 在這里,我們只引用包含集合的UCItemsSource
屬性,在這里還用RelativeSource
證明了這一點:
UserControl
XAML
<Grid>
<ItemsControl ItemsSource="{Binding Path=UCItemsSource,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type UserControl}}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Code-behind
public partial class UserControl1 : UserControl
{
#region Public Section
public ObservableCollection<long> UCItems { get; set; }
#endregion
public UserControl1()
{
InitializeComponent();
UCItems = new ObservableCollection<long>();
}
#region UCItemsSource Property
public static readonly DependencyProperty UCItemsSourceProperty = DependencyProperty.Register("UCItemsSource",
typeof(IEnumerable),
typeof(UserControl1));
public IEnumerable UCItemsSource
{
get { return (IEnumerable)GetValue(UCItemsSourceProperty); }
set { SetValue(UCItemsSourceProperty, value); }
}
#endregion
}
嘗試這個
private ObservableCollection<long> _windowCollection
public ObservableCollection<long> WindowCollection
{
get { return _windowCollection; }
set
{
_windowCollection = value;
RaiseOnPropertyChange(() => WindowCollection);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.