将 ObservableCollection<object> 传递给 UserControl

Pass a ObservableCollection<object> to UserControl

我一直在尝试概括将 ObservableCollection 传递给此处提供的 UserControl 的解决方案:

How to bind collection dependency property in UserControl

我将 UserControl 后面的代码更改为:

/// <summary>
/// Interaction logic for myUserControl1.xaml
/// </summary>
public partial class myUserControl1 : UserControl
{
    #region Public Section
    public ObservableCollection<object> UCItems
    {
        get;
        set;
    }

    #endregion
    public myUserControl1()
    {
        InitializeComponent();

        UCItems = new ObservableCollection<object>();
    }

    #region UCItemsSource Property

    public static readonly DependencyProperty UCItemsSourceProperty = 
        DependencyProperty.Register("UCItemsSource", typeof(IEnumerable), typeof(myUserControl1));

    public IEnumerable UCItemsSource
    {
        get { return (IEnumerable)GetValue(UCItemsSourceProperty); }
        set { SetValue(UCItemsSourceProperty, value); }
    }

    #endregion
}

并在 xaml 中将 TexBox 更改为 DataGrid:

<UserControl x:Class="OCasDPdemo.myUserControl1"
         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:OCasDPdemo"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<Grid>
    <ItemsControl ItemsSource="{Binding Path=UCItemsSource, 
                                    RelativeSource={RelativeSource Mode=FindAncestor,
                                                                   AncestorType={x:Type UserControl}}}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <DataGrid x:Name="myDataGrid" ItemsSource="{Binding Path=UCItemsSource.Person}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

我以与原始示例类似的方式填充集合:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public ObservableCollection<Person> WindowCollection
    {
        get;
        set;
    }
    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;


        var bob = new Person { FirstName = "Bob", LastName = "Brown", Age = 32.1, ID = 101 };
        var jim = new Person { FirstName = "Jim", LastName = "Green", Age = 21.0, ID = 201 };
        var mel = new Person { FirstName = "Mel", LastName = "Black", Age = 20, ID = 111 };

        WindowCollection = new ObservableCollection<Person>() {bob, jim, mel };
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var sue = new Person { FirstName = "Sue", LastName = "White", Age = 64.7, ID = 101 };
        var ted = new Person { FirstName = "Ted", LastName = "Grey", Age = 18.3, ID = 191 };

        WindowCollection.Add(sue);
        WindowCollection.Add(ted);
    }
}

并且 MainWindow xaml 是:

<Grid>
    <StackPanel>
        <local:myUserControl1 UCItemsSource="{Binding Path=WindowCollection}" />
        <Button Content="Refresh" Click="Button_Click" />
    </StackPanel>
</Grid>

我得到的是空行(与人数相同)而不是带列的网格。此设置适用于原生类型,如长整型和字符串类型(使用 TextBox)。有人可以让我知道我做错了什么吗?

我自己还没有尝试过,但问题似乎出在你的 myUserControl1 XAML.

就在根 Grid 内是一个 ItemsControlItemsSource 绑定到 UCItemsSource。这意味着 ItemsControl 将为该集合中的每个元素生成一个 ContentPresenter - 在您的情况下将是您的 Persons.

列表

现在,在每个 ContentPresenter 中,将创建一个 DataTemplate 的实例。您的 DataTemplate 包含一个 DataGrid。这意味着每 Person.

您将得到一个完整的 DataGrid

如果您尝试让一个 DataGrid 每个 Person 一行,您可能需要这样的东西:

<UserControl x:Class="OCasDPdemo.myUserControl1"
         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:OCasDPdemo"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <DataGrid x:Name="myDataGrid" ItemsSource="{Binding Path=UCItemsSource, 
                                                        RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                       AncestorType={x:Type UserControl}}}">
            
        </DataGrid>
    </Grid>
</UserControl>