2016-09-20 255 views
0

我有一个UserControl,它具有包含我自己的自定义类的实例的ViewModel,将其称为Person。这个ViewModel被设置为控件的DataContext。我想在我的主窗口中使用这个控件,在它的ViewModel中有一个名为People的人员名单。我打电话给我的xaml中的控件,如下所示:数据绑定项目控件中的用户控件

<ItemsControl ItemsSource="{Binding People}"> 
    <ItemsControl.ItemsTemplate> 
     <DataTemplate> 
      <userControls:PersonDetails /> 
     </DataTemplate> 
    </ItemsControl.ItemsTemplate> 
</ItemsControl> 

控件中的属性以这种方式绑定。

<TextBlock Text="{Binding Person.Name}" /> 

当我运行时,我得到正确数量的控件的人数在列表中,但没有详细信息填充。我知道我正在做一些简单的错误,但找不到它。请帮忙。

编辑:

我的用户XAML看起来是这样的:

<UserControl x:Class="AddressBook.UserControls.PersonDetails" 
     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:AddressBook.UserControls" 
     xmlns:vm="clr-namespace:AddressBook.ViewModels" 
     xmlns:enums="clr-namespace:AddressBook.Models" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="1000">  

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="40" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 

    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition Width="1*" /> 
    </Grid.ColumnDefinitions> 

    <TextBlock Style="{StaticResource PersonDetailHeader}" Text="Person Name:" /> 

    <TextBlock Style="{StaticResource PersonDetailValue}" Grid.Column="1" Text="{Binding Person.Name, 
       UpdateSourceTrigger=PropertyChanged}" /> 

    <TextBlock Style="{StaticResource PersonDetailHeader}" VerticalAlignment="Center" Grid.Row="1" Text="Street Address:" /> 

    <TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="1" Grid.Column="1" 
       Text="{Binding Person.StreetAddress, UpdateSourceTrigger=PropertyChanged}" /> 

    <TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="2" Text="Town:" /> 

    <TextBlock Style="{StaticResource PeronDetailValue}" Grid.Row="2" Grid.Column="1" 
       Text="{Binding Person.Town, UpdateSourceTrigger=PropertyChanged}" /> 

    <TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="3" Text="County:" /> 

    <TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="3" Grid.Column="1" 
       Text="{Binding Person.County, UpdateSourceTrigger=PropertyChanged}" /> 

    <TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="4" Text="Postcode:" /> 

    <TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="4" Grid.Column="1" 
       Text="{Binding Person.Postcode, UpdateSourceTrigger=PropertyChanged}" /> 

    <TextBlock Style="{StaticResource PersonDetailHeader}" Grid.Row="5" Text="Phone:" /> 

    <TextBlock Style="{StaticResource PersonDetailValue}" Grid.Row="5" Grid.Column="1" 
       Text="{Binding Person.Phone, UpdateSourceTrigger=PropertyChanged}" /> 

    <StackPanel Grid.Row="7" Grid.ColumnSpan="2" HorizontalAlignment="Center" Orientation="Horizontal"> 
     <Button Style="{StaticResource ButtonStyle}" Content="Click" Command="{Binding ButtonClickCommand}" /> 

    </StackPanel> 
</Grid> 

用户控件视图模型:

public class PersonDetailsViewModel 
{ 
    public Person Person { get; set; } 

    public Command ButtonClickCommand { get; } 

    public PersonDetailsViewModel() 
    { 
     ButtonClickCommand = new Command(ButtonClick); 
    } 

    private void ButtonClick(object obj) 
    { 
     throw new NotImplementedException(); 
    } 

UserControl.xaml.cs:

public partial class PersonDetails : UserControl 
{ 
    public PersonDetails() 
    { 
     InitializeComponent(); 
    } 
} 

Person.cs

public class Person : BaseModel 
{ 
    public string Name 
    { 
     get { return name; } 
     set 
     { 
      name = value; 

      NotifyPropertyChanged(); 
     } 

等....

MainViewModel:

public class MainViewModel : BaseViewModel 
{ 
    public ObservableCollection<Person> People { get; } 
     = new ObservableCollection<Person>(); 

    public MainViewModel() 
    { 
     PopulatePeople(); 
    } 
} 
+0

监听用户控制的数据上下文已更改事件并检查您正在获取的数据上下文。无论是你想要的,也就是你的人员课程是否正确? – Versatile

+0

灰 - 输出中无绑定错误。 –

+0

Silvermind - 谢谢,但这没有奏效。 Versatile - DataContextChanged事件甚至没有触发,所以它显然没有被设置。 –

回答

1

Now I了解为什么要在UserControl XAML中创建PersonDetailsViewModel,以及该命令的问题是什么。

解决此问题的最简单方法是使MainViewModel.People集合PersonDetailsViewModel而不是Person。这就是我要做的。

但是,如果您想离开MainViewModel.People原样,但在UserControl内仍然使用PersonDetailsViewModel,这对我来说很合理。你可以这样做:

的.xaml

<UserControl 
    x:Class="AddressBook.UserControls.PersonDetails" 
    DataContextChanged="PersonDetails_DataContextChanged" 

    ...etc... 

    > 

    <!-- Give the Grid a name... --> 
    <Grid x:Name="OuterGrid"> 

的.xaml。CS现在

public PersonDetails() 
{ 
    InitializeComponent(); 
} 

private void PersonDetails_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) 
{ 
    // ...so we can give the Grid a different DataContext 
    OuterGrid.DataContext = new PersonDetailsViewModel { 
     Person = (Person)this.DataContext 
    }; 
} 

会继承其DataContext一个Person,但是在内部它会使用PersonDetailsViewModel基于该Person

0

不知道如果这就是你正在尝试做的。 如果你只是想显示你的人名单存在于每个人的一些carac你可以这样做:

 <Grid> 
      <ItemsControl ItemsSource="{Binding People}"> 
        <ItemsControl.ItemTemplate> 
          <DataTemplate> 
            <Grid Margin="0,0,0,5"> 
              <Grid.ColumnDefinitions> 
                <ColumnDefinition Width="*" /> 
                <ColumnDefinition Width="100" /> 
              </Grid.ColumnDefinitions> 
              <TextBlock Text="{Binding Name}" /> 
              <TextBlock Grid.Column="1" Text="{Binding Age}" /> 
            </Grid> 
          </DataTemplate> 
        </ItemsControl.ItemTemplate> 
      </ItemsControl> 
    </Grid> 

将结合您文本对列表中的每个元素的名称属性,所以每个名称你的名单中的人。 由于您的ItemsSource已经绑定到People,所以您的Items的绑定已经在List的每个Person上,所以您应该直接调用您的属性作为{Binding Name}而不是{Binding Person.Name}

+0

感谢您的帮助,但在用户控件(如联系人卡片)中还有其他字段要显示,我只是省略了它们,因为它们都没有显示,并且都以相同的方式绑定。 –

+0

您的UserControl是另一个使用选定人员填充的窗口吗?或者它是一个网格,包含所有的人和他们的信息? – Belterius

+0

我编辑了我的答案,所以它可以对应于你想要的 – Belterius