代码之家  ›  专栏  ›  技术社区  ›  Sach

数据绑定到UserControl内部的UserControl[重复]

  •  3
  • Sach  · 技术社区  · 7 年前

    在我的项目中,我需要将数据绑定到驻留在另一个UserControl中的UserControl。为了简洁起见,我创建了一个概念相似但非常简单的项目。

    假设我正在创建一个电话簿应用程序,其中包含两个用户控件,如下所示。

    enter image description here

    窗口中的蓝色大框是一个UserControl,显示所有者的姓名(Jane Doe),其中的每个黄色框也是UserControl,显示联系人的姓名和电话号码。

    我有两个类保存相关数据,如下所示:

    public class Person
    {
        public string Name { get; set; }
        public string Phone { get; set; }
        public Person() { }
    }
    
    public class PhoneBook
    {
        public string OwnerName { get; set; }
        public ObservableCollection<Person> ContactList { get; set; }
        public PhoneBook() { }
    }
    

    在我的 MainWindow ,我使用ViewModel并绑定到 PhoneBook 像这样的用户控件:

    <Window x:Class="UserControlDataBinding.MainWindow"
            Title="MainWindow" Height="300" Width="350"
            DataContext="{Binding Source={StaticResource mainViewModelLocator},Path=ViewModelPhoneBook}">
        <Grid>
            <local:UCPhoneBook x:Name="ucPhoneBook" MainPhoneBook="{Binding PhoneBookData}"></local:UCPhoneBook>
        </Grid>
    </Window>
    

    PhoneBookData 是的实例 通信录 在ViewModel上初始化。

    我的两个用户控件及其 DependancyProperties 如下所示。

    UCPhoneBook用户控件(蓝色框):

    这里我用的是 ItemsControl 动态绑定 UCPerson 用户控件,以便我可以在运行时添加任意数量的控件。

    <UserControl x:Class="UserControlDataBinding.UCPhoneBook"
                 d:DesignHeight="300" d:DesignWidth="450">
        <Canvas x:Name="ucCanvasPhoneBook" Background="White">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <GroupBox Grid.Row="0" Header="Phonebook">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Label Grid.Row="0" Name="lblOwnerName" 
                               Content="{Binding Path=MainPhoneBook.OwnerName}">
                        </Label>
                    </Grid>
                </GroupBox>
    
                <ItemsControl Grid.Row="1"
                              ItemsSource="{Binding PhoneBookData.ContactList}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate DataType="{x:Type local:Person}">
                            <local:UCPerson PersonData="{Binding Person}"></local:UCPerson>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Vertical"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </Grid>
        </Canvas>
    </UserControl>
    

    它的 DependancyProperty :

    public partial class UCPhoneBook : UserControl
    {
        private static readonly DependencyProperty PhoneBookProperty = DependencyProperty.Register("MainPhoneBook", typeof(PhoneBook), typeof(UCPhoneBook), new PropertyMetadata(null));
        public PhoneBook MainPhoneBook
        {
            get { return (PhoneBook)GetValue(PhoneBookProperty); }
            set { SetValue(PhoneBookProperty, value); }
        }
    
        public UCPhoneBook()
        {
            InitializeComponent();
            ucCanvasPhoneBook.DataContext = this;
        }
    }
    

    UCPerson用户控件(黄色框):

    <UserControl x:Class="UserControlDataBinding.UCPerson"
                 d:DesignHeight="26" d:DesignWidth="400">
        <Canvas x:Name="ucCanvasPerson" Background="WhiteSmoke">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Name="lblName" 
                       HorizontalAlignment="Left" VerticalAlignment="Center"
                       Content="{Binding Name}"></Label>
                <Label Grid.Column="2" Name="lblPhone" 
                       HorizontalAlignment="Right" VerticalAlignment="Center"
                       Content="{Binding Phone}"></Label>
            </Grid>
        </Canvas>
    </UserControl>
    

    它的 依赖性财产 :

    public partial class UCPerson : UserControl
    {
        private static readonly DependencyProperty PersonProperty = DependencyProperty.Register("PersonData", typeof(Person), typeof(UCPerson), new PropertyMetadata(null));
        public Person PersonData
        {
            get { return (Person)GetValue(PersonProperty); }
            set { SetValue(PersonProperty, value); }
        }
    
        public UCPerson()
        {
            InitializeComponent();
            ucCanvasPerson.DataContext = this;
        }
    }
    

    当我运行它时,我可以在第一个UserControl(蓝色框)的顶部看到所有者的名字。但是,它似乎无法正确绑定 UCPerson公司 用户控件,我得到一个空列表,如下所示:

    enter image description here

    我猜我没有正确地绑定到 项目控制 在第一个UserControl内。我对数据绑定非常陌生,似乎不知道正确的方法是什么。

    我做错了什么?

    1 回复  |  直到 7 年前
        1
  •  6
  •   15ee8f99-57ff-4f92-890c-b56153    4 年前

    这一切都可以大大简化。

    首先,摆脱 Canvas 在您的 UserControl s Canvas isn't just a neutral panel/container control . 这个 帆布 es将导致所有内容重叠。仅使用 帆布 当您想要任意定位子对象时,可能会叠加。WPF布局通常使用“流”和相对定位。标准布局父级是 StackPanel , Grid , WrapPanel ,以及偶尔 UniformGrid . 您可以省略 ItemsPanelTemplate 对于 ItemsControl ,因为默认值已经是垂直方向的 堆栈面板 .