UserControl的自定义ItemsSource属性

时间:2012-02-27 04:21:34

标签: wpf data-binding itemssource

有谁知道如何制作自定义ItemsSource

我想要做的是为自己的itemsSource制作一个UserControl,以便它可以被ObservableCollection<>约束。

另外,我可以知道每当itemsSource中的项目数量更新,以便做进一步的程序。

非常感谢你。

3 个答案:

答案 0 :(得分:34)

您可能需要在控件中执行类似的操作

public IEnumerable ItemsSource
{
    get { return (IEnumerable)GetValue(ItemsSourceProperty); }
    set { SetValue(ItemsSourceProperty, value); }
}

public static readonly DependencyProperty ItemsSourceProperty =
    DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(UserControl1), new PropertyMetadata(new PropertyChangedCallback(OnItemsSourcePropertyChanged)));

private static void OnItemsSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    var control = sender as UserControl1;
    if (control != null)
        control.OnItemsSourceChanged((IEnumerable)e.OldValue, (IEnumerable)e.NewValue);
}



private void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
    // Remove handler for oldValue.CollectionChanged
    var oldValueINotifyCollectionChanged = oldValue as INotifyCollectionChanged;

    if (null != oldValueINotifyCollectionChanged)
    {
        oldValueINotifyCollectionChanged.CollectionChanged -= new NotifyCollectionChangedEventHandler(newValueINotifyCollectionChanged_CollectionChanged);
    }
    // Add handler for newValue.CollectionChanged (if possible)
    var newValueINotifyCollectionChanged = newValue as INotifyCollectionChanged;
    if (null != newValueINotifyCollectionChanged)
    {
        newValueINotifyCollectionChanged.CollectionChanged += new NotifyCollectionChangedEventHandler(newValueINotifyCollectionChanged_CollectionChanged);
    }

}

void newValueINotifyCollectionChanged_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    //Do your stuff here.
}

答案 1 :(得分:7)

在CustomControl中使用DependencyProperty ItemsSource,然后绑定到此DependencyProperty

这是XAML代码(识别ListBox的DataContext):

<UserControl
    x:Name="MyControl">
    <ListBox
        DataContext="{Binding ElementName=MyControl}"
        ItemsSource="{Binding ItemsSource}">
    </ListBox>
</UserControl>

这是CodeBehind:

public partial class MyCustomControl
{
    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(IEnumerable),
            typeof(ToolboxElementView), new PropertyMetadata(null));
}

这是您使用“MyCustomControl”的代码:

<Window>
    <local:MyCustomControl
        ItemsSource="{Binding MyItemsIWantToBind}">
    </local:MyCustomControl>
</Window>

答案 2 :(得分:0)

简化的答案。

    public IEnumerable ItemsSource
    {
        get => (IEnumerable)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(UserControl1), new PropertyMetadata(null, (s, e) =>
        {
            if (s is UserControl1 uc)
            {
                if (e.OldValue is INotifyCollectionChanged oldValueINotifyCollectionChanged)
                {
                    oldValueINotifyCollectionChanged.CollectionChanged -= uc.ItemsSource_CollectionChanged;
                }

                if (e.NewValue is INotifyCollectionChanged newValueINotifyCollectionChanged)
                {
                    newValueINotifyCollectionChanged.CollectionChanged += uc.ItemsSource_CollectionChanged;
                }
            }
        }));

    private void ItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // Logic Here
    }

    // Do Not Forget To Remove Event On UserControl Unloaded
    private void UserControl1_Unloaded(object sender, RoutedEventArgs e)
    {
        if (ItemsSource is INotifyCollectionChanged incc)
        {
            incc.CollectionChanged -= ItemsSource_CollectionChanged;
        }
    }