【发布时间】:2017-07-20 00:48:21
【问题描述】:
我对 WPF 非常陌生,并且在创建绑定时尝试使用 Knockout JS 作为类比。我听说 WPF 的绑定引擎更强大,但我正在努力解决在 Knockout 中很容易解决的问题。
假设我有一个包含地址集合的 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 中,我不确定如何分配绑定以同时使用父元素和当前元素属性;它是否可以从它们中创建一个对象,甚至只是调用一个方法并从两者中获取参数。
在淘汰赛中,您只需绑定函数并访问父上下文,例如:
<!-- 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 -->
我似乎不知道如何在 XAML 中做同样的事情。
<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
}
【问题讨论】:
-
你不需要绑定到标签。单击按钮的数据上下文是地址。 ((Button)sender).DataContext 作为地址。
-
@MarkW 感谢您的提示!
标签: c# wpf xaml data-binding