绑定到另一个usercontrol

时间:2014-04-28 13:54:15

标签: c# wpf xaml binding user-controls

我刚刚开始使用WPF,我正试图围绕XAML Bindings。 经过大量的阅读后,我认为我有一个足够简单的用例来测试我的知识。但是纳达:-(我无法弄明白。

我要做的是以下内容: 我有地址对象:

public IEnumerable<Address> Addresses
{
    get
    {
        if (addresses == null)
        {
            addresses = new Repository<Address>().GetAll().ToList<Address>();
        }
        return addresses;
    }
}

有租赁对象,例如

address.Rentals

也是IList。 在我的MainWidow上,我希望有2个UserControl,一个用于地址,一个用于租赁信息。如果我单击地址用户控件上的导航器,我只想查看当前地址的租借记录。

主窗口

<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(地址)中collectionNavigator的CurrentItem

但我无法弄清楚如何。我尝试了很多东西,包括Binding Path和RelativeSource,但似乎都没有用。我能让它工作的唯一方法是将UserControl1的内容复制到我的MainWindow.xaml中,但是我无法重复使用它。

非常感谢任何帮助。

更新&gt;&gt;&gt;&gt;&gt;

Sheridan的工作解决方案。

MainWindows

...
<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));

2 个答案:

答案 0 :(得分:2)

您可以使用"/" Binding表示法对数据绑定当前项目。尝试这样的事情:

<UserControl Name="Control1" DataContext="{Binding SomeCollection}" />

<UserControl Name="Control2" DataContext="{Binding SomeCollection/}" />

Binding SomeCollection/表示绑定到SomeCollection集合的当前项。要使其工作,您可能需要在要选择当前项目的任何容器控件上将Selector.IsSynchronizedWithCurrentItem Property设置为True

<ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" ... />

更新&gt;&gt;&gt;

如果没有IsSynchronizedWithCurrentItem属性,"/" Binding符号将无法使用。相反,您可以在相关DependencyProperty上将所选项目作为UserControl从集合中公开。然后你可以做这样的事情:

<UserControl Name="Control2" DataContext="{Binding SelectedItem, ElementName=Control1}" />

答案 1 :(得分:0)

您可以通过将CurrentItem绑定到viewModel来提供viewModel中的Rentals,并公开这样的Rentals:

<telerik:RadCollectionNavigator CurrentItem={Binding CurrentItem} />

public Address CurrentItem
    {
       get; set;
    }

public IEnumerable<Rentals> Rentals
{
   get { return CurrentItem.Rentals; }

}