2017-02-28 32 views
1

私はWPFにとって非常に新しく、バインディングを作成する際にKnockout JSをアナロジーとして使用しようとしています。私はWPFのバインディングエンジンがさらに強力だと聞いたが、私はノックアウトで簡単なもので苦労している。WPF現在の要素と親要素のプロパティへのバインド

住所のコレクションを持つPersonクラスがあるとします。

public class Person 
{ 
    public string PersonId {get;set;} 
    public IList<Address> Addresses{get; set;} 
    public string FormattedName{get;set;} 
} 

public class Address 
{ 
    public string AddressId{get;set;} 
    public string Address1{get;set;} 
    public string City{get;set;} 
    public string State{get;set;} 
    public string Zip{get;set;} 
} 

人が集まっていると思いますが、人それぞれについて、すべてのアドレスを表示し、アドレスを選択するボタンを用意したいと思います。だから、私のページビューモデルは次のようになります。

public class AddressSelection 
{ 
    public string PersonId{get;set;} 
    public string AddressId{get;set;} 
} 

public class PersonAddressSelectionViewModel 
{ 
    public IList<Person> People {get; set;} 

    public Person SelectedPerson {get;set;} 
    public Address SelectedAddress{get;set;} 

    public void SelectAddress(string personId, string addressId) 
    { 
     this.SelectedPerson = this.People.FirstOrDefault(x => x.PersonId == personId); 
     this.SelectedAddress = this.SelectedPerson?.Addresses.FirstOrDefault(x => x.AddressId == addressId); 
    } 

    public void SelectAddress(AddressSelection arg) 
    { SelectAddress(arg.PersonId, arg.AddressId); } 
} 

、私はその後、各乗客のヘッダ、各アドレスのボタンを示してUIを表示したいです。ボタンが選択されると、SelectAddress関数がトリガされるはずです。しかし、XAMLでは、親要素と現在の要素プロパティの両方を使用するようにバインディングを割り当てる方法がわかりません。オブジェクトからオブジェクトを作成したり、メソッドを呼び出したり、両方から引数を取得したりすることができます。

ノックアウトでは、あなただけの機能を結合したいと同様に親コンテキストにアクセスします。私は、XAMLで同じことを行う方法を見つけ出すように見えることはできません

<!-- ko foreach: $data.people --> 
<h2 data-bind="text: formattedName"></h2> 
<ul data-bind="foreach: $data.addresses"> 
    <li> 
     <button data-bind="click: function() { $parents[1].selectAddress($parent.personId, $data.addressId); }">Select Address</button> 
    </li> 
</ul> 
<!-- /ko --> 

。背後にあるコードで

<ItemsControl Grid.Row="2" ItemsSource="{x:Bind ViewModel.People, Mode=OneWay}" 
    HorizontalAlignment="Center" Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal" Margin="5"> 
       <TextBlock Style="{StaticResource TextBlockSmallStyle}" VerticalAlignment="Center" Width="180" Text="{Binding FormattedName, Mode=OneWay}" /> 
       <ItemsControl ItemsSource="{Binding Addresses}" Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <VirtualizingStackPanel Orientation="Horizontal" /> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal"> 
           <Button Width="180" Style="{StaticResource ButtonStyle}" 
           Content="{Binding Address1}" 
           Click="SelectAddressClicked" Tag="{Binding **what to put here**}" /> 
          </StackPanel> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

SelectAddressClicked(object sender, object args) { 
    ((Button)sender).Tag as Address; // would prefer this to be something that has both the address id and person id 
} 
+0

タグにバインドする必要はありません。クリックされたボタンのdatacontextはAddressです。 ((Button)sender)。AddressとしてのDataContext。 –

+0

@MarkWチップをありがとう! – MPavlak

答えて

0

はあなたが

は、あなたのビューモデルに以下の定義を追加

グーグルRelayCommandクラスの実装の後ろの代わりにコードのMVVMでこれを行う必要があります

public RelayCommand SelectAddressCommand { get; private set; } 
コンストラクタで

SelectAddressCommand = new RelayCommand(args => SelectAddress(args)); 
XAMLで

<Button Command={Binding SelectAddressCommand} 
     CommandParameter={...} 

しかし、私の理解に基づいて、あなたはListBox代わりのItemsControlを使って自分でトラブルのトンを保存することができます。それはSelectedItemプロパティが組み込まれているだけで直接あなたのビューモデルにバインドすることができます

+0

私は後ろにコードの代わりにリレーを使用しても、現在のコンテキストと親コンテキストから引数を構築する方法は? – MPavlak

+0

@MPavlakはRelativeResourceを参照するSelf/FindAncestor – Steve

+0

相対的なリソースであっても、私にはどちらかの状況が与えられません。私は両方のオブジェクトから何かが必要です。違いがある場合、これはuwpアプリであり、この質問を参照として使用しようとしています。http://stackoverflow.com/questions/32861612/how-to-do-relativesource-mode-find-ancestor-or私の最後の文章で言ったように、私は同じようにuwp – MPavlak

関連する問題