2016-09-20 252 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