绑定到另一个用户控件

本文关键字:控件 用户 另一个 绑定 | 更新日期: 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; }
}