绑定到另一个用户控件
本文关键字:控件 用户 另一个 绑定 | 更新日期: 2023-09-27 18:00:27
我刚开始使用WPF,我正试图了解XAML绑定。经过大量的阅读,我认为我有一个足够简单的用例来测试我的知识。但是纳达:-(我想不通。
我想做的是:我有地址对象:
public IEnumerable<Address> Addresses
{
get
{
if (addresses == null)
{
addresses = new Repository<Address>().GetAll().ToList<Address>();
}
return addresses;
}
}
有租赁对象,例如
address.Rentals
也称为IList。在我的MainWidow上,我想要两个UserControls,一个用于地址,另一个用于租赁信息。如果我单击地址用户控件上的导航器,我只想查看当前地址的租赁记录。
主窗口
<Window x:Class="Swopt.Mira.WPFApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:local="clr-namespace:Swopt.Mira.WPFApp"
Title="MainWindow" Height="500" Width="525">
<Window.Resources>
<sampleData:DataContext x:Key="testDataContext" />
</Window.Resources>
<Grid x:Name="rootGrid" Background="White" DataContext="{StaticResource testDataContext}">
<StackPanel>
<local:RentalCustomer x:Name="rentalCustomer" Height="100" />
<local:Rentals Height="100" />
</StackPanel>
</Grid>
地址
<UserControl
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:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="Swopt.Mira.WPFApp.RentalCustomer"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="RentalCustomerUserControl">
<Grid x:Name="rootGrid" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<StackPanel>
<TextBlock Text="Firma1"/>
<TextBox x:Name="Firma1" Text="{Binding ElementName=collectionNavigator, Path=CurrentItem.Firma1}" />
</StackPanel>
<telerik:RadCollectionNavigator Grid.Row="1"
Height="30"
Margin="2"
Grid.ColumnSpan="2"
x:Name="collectionNavigator"
Source="{Binding Addresses}"
/>
</Grid>
租金
<UserControl
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:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="Swopt.Mira.WPFApp.Rentals"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="RentalsUserControl">
<Grid x:Name="rootGrid" Background="White" >
<StackPanel>
<TextBlock Text="VertragsNr"/>
<TextBox x:Name="VertragsNr" Text="{Binding ElementName=collectionNavigator2, Path=CurrentItem.VertragsNr}" />
</StackPanel>
<telerik:RadCollectionNavigator Grid.Row="1"
Height="30"
Margin="2"
x:Name="collectionNavigator2"
Source="{Binding Rentals}" />
</Grid>
本质上,我想做的是将UserControl2(Rentals)的DataContext绑定到UserControl1(Addresses)中collectionNavigator的CurrentItem
但我不知道怎么做。我尝试了很多方法,使用BindingPath和RelativeSource,但似乎都不起作用。我能让它工作的唯一方法是将UserControl1的内容复制到我的MainWindow.xaml中,但之后我就不能重用它了
非常感谢您的帮助。
更新>>>>
Sheridan的工作解决方案。
主窗口
...
<local:RentalCustomer x:Name="rentalCustomer" Height="400" />
<local:Rentals Height="100" DataContext="{Binding CurrentAddress, ElementName=rentalCustomer}" />
RentalCustomer.xaml
...
<telerik:RadCollectionNavigator Grid.Row="1"
Height="30"
Margin="2"
Grid.ColumnSpan="2"
x:Name="collectionNavigator"
Source="{Binding Addresses}"
CurrentItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=CurrentAddress, Mode=OneWayToSource}"
/>
RentalCustomer.xaml.cs
public Address CurrentAddress
{
get { return (Address)GetValue(CurrentAddressProperty); }
set { SetValue(CurrentAddressProperty, value); }
}
// Using a DependencyProperty as the backing store for CurrentAddress. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CurrentAddressProperty =
DependencyProperty.Register("CurrentAddress", typeof(Address), typeof(RentalCustomer), new PropertyMetadata(null));
您可以使用"/"
Binding
表示法对集合的当前项进行数据绑定。试试这样的东西:
<UserControl Name="Control1" DataContext="{Binding SomeCollection}" />
<UserControl Name="Control2" DataContext="{Binding SomeCollection/}" />
Binding SomeCollection/
表示绑定到SomeCollection
集合的当前项。为了实现这一点,您可能需要在中选择当前项的任何容器控件上将Selector.IsSynchronizedWithCurrentItem
属性设置为True
<ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" ... />
更新>>>
如果没有IsSynchronizedWithCurrentItem
属性,"/"
Binding
表示法就无法工作。相反,您可以在相关的UserControl
上将集合中的选定项公开为DependencyProperty
。然后你可以做这样的事情:
<UserControl Name="Control2" DataContext="{Binding SelectedItem, ElementName=Control1}" />
您可以通过将CurrentItem绑定到您的viewModel来提供viewModel中的Rental,并像这样公开Rental:
<telerik:RadCollectionNavigator CurrentItem={Binding CurrentItem} />
public Address CurrentItem
{
get; set;
}
public IEnumerable<Rentals> Rentals
{
get { return CurrentItem.Rentals; }
}