开发者

Binding from View-Model to View-Model of a child User Control in Silverlight? 2 sources - 1 target

So i have a UserControl for one of my Views and have another 'child' UserControl inside that.

The outer 'parent' UserControl has a Collection on its View-Model and a Grid control on it to display a list of Items.

I want to place another UserControl inside this UserControl to display a form representing the details of one Item.

The parent UserControl's View-Model already has a property on it to hold the currently selected Item and i would like to bind this to a DependancyProperty on the child UserControl. I would then like to bind that DependancyProperty to a property on the child UserControl's View-Model.

I can then set the DependancyProperty once in XAML with a binding expression and have the child UserControl do all its work in its View-Model like it should.

The code i have looks like this..

Parent UserControl:

<UserControl x:Class="ItemsListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  开发者_运维知识库  DataContext="{Binding Source={StaticResource ServiceLocator}, Path=ItemsListViewModel}">
    <!-- Grid Control here... -->
    <ItemDetailsView Item="{Binding Source={StaticResource ServiceLocator}, Path=ItemsListViewModel.SelectedItem}" />
</UserControl>

Child UserControl:

<UserControl x:Class="ItemDetailsView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding Source={StaticResource ServiceLocator}, Path=ItemDetailsViewModel}"
    ItemDetailsView.Item="{Binding Source={StaticResource ServiceLocator}, Path=ItemDetailsViewModel.Item, Mode=TwoWay}"> 
    <!-- Form controls here... -->
</UserControl>

EDIT: Heres how i created the Dependancy Proeprty on the child UC:

public partial class ItemDetailsView : UserControl
{
    private static readonly DependencyProperty itemProperty;

    static ItemDetailsView()
    {
        ItemDetailsView.itemProperty = DependencyProperty
            .Register("Item", typeof(Item), typeof(ItemDetailsView), null);
    }

    public Item Item
    {
        get { return (Item)GetValue(ItemDetailsView.itemProperty); }
        set { SetValue(ItemDetailsView.itemProperty, value); }
    }

    public static Item GetItem(DependencyObject target)
    {
        return (Item)target.GetValue(itemProperty);
    }

    public static void SetItem(DependencyObject target, Item value)
    {
        target.SetValue(itemProperty, value);
    }
}

The selected Item is bound to the DependancyProperty fine. However from the DependancyProperty to the child View-Model does not.

It appears to be a situation where there are two concurrent bindings which need to work but with the same target for two sources.

Why won't the second (in the child UserControl) binding work?? Is there a way to acheive the behaviour I'm after??

Cheers.


Well, it looks like you are trying to use a "normal" DependencyProperty on the parent UserControl, and an "attached" DependencyProperty on the child UserControl. You need to pick one way. :)

EDIT for clarification: There are two ways of registering a dependency property, "Normal", like so:

public static readonly DependencyProperty BobProperty = 
    DependencyProperty.Register("Bob",....)

and Attached:

public static readonly DependencyProperty BobAttachedProperty = 
    DependencyProperty.RegisterAttached("BobAttached",...)

Let's say the control you are registering these properties on is called "MyPanel". To use each property:

<MyPanel Bob="somevalue" MyPanel.BobAttached="somevalue"/>

Note the need to specify "where the attached property is defined". Attached properties are great when you have some bit of behavior or functionality that applies to multiple types of controls.

That said, perhaps there is a better way to do this - If the parent UserControl contained an ItemsControl, the ItemTemplate for that control could be a DataTemplate that contained the ItemDetailsView, in which case you could use standard data binding to do what you needed to:

<UserControl blahblahblah>
    <ItemsControl ItemsSource="{Binding WhereYourItemsAre}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
               <ns:WhatYourChildViewIsCalled DataContext="{Binding}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</UserControl>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜