2012-02-28 55 views
2

绑定到的DependencyProperty我有两个不同的用户控件形式 - 一个包含一个Telerik的RadGridView,另一个是包含Telerik的的DataForm。在用户控件

网格用户控件绑定到包括暴露的网格绑定到项目集合的属性一个ViewModel。

当我在窗体绑定到财产,一切工作正常。
但我需要访问窗体控件​​中的其他信息,它们不属于网格控件的视图模型。

所以我想我会一个属性添加到窗体用户控件,并将其绑定到项目集合:

<local:FormControl x:Name="formControl" 
    ItemsSource="{Binding items}" 
/> 

在窗体的代码隐藏,我添加了一个普通财产:

private object itemsSource; 
public object ItemsSource 
{ 
    get { return this.itemsSource; } 
    set { this.itemsSource = value; } 
} 

这当然不起作用。我遇到了必须使用DependencyProperty的错误。我认为这是令人放心的 - 页面实际上是试图绑定到我认为应该的属性。

所以我转换这对DependencyProperty:

public static DependencyProperty ItemsSourceProperty = 
    DependencyProperty.Register("ItemsSource", typeof(object), typeof(FormControl)); 

public object ItemsSource 
{ 
    get { return GetValue(ItemsSourceProperty); } 
    set { SetValue(ItemsSourceProperty, value); } 
} 

这编译和无差错运行。当然,除了该控件的视图模型没有任何项目。所以接下来是试图ItemsSource属性传递到表单控件的视图模型:

public FormControl() 
{ 
    InitializeComponent(); 
    this.DataContext = new FormControlVM(this.ItemsSource); 
    ... 

这没有奏效。当FormControl()被构造时ItemsSource为null。所以我向viewmodel添加了一个setItemsSource()方法,并在ItemsSource属性的set函数中调用它。这也没有奏效。 xaml显然是绑定到属性的,但似乎没有调用属性的set函数。

所以我决定听ValueChanged事件,上的DependencyProperty:

public FormControl() 
{ 
    InitializeComponent(); 
    this.DataContext = new FormControlVM(); 
    DependencyPropertyDescriptor prop = 
      DependencyPropertyDescriptor.FromProperty(FormControl.ItemsSourceProperty, this.GetType()); 
    prop.AddValueChanged(this, delegate 
    { 
     FormControlVM formControlVM = (FormControlVM)this.DataContext; 
     formControlVM.setItemsSource(this.ItemsSource); 
    }); 
    ... 

,它仍然无法正常工作。 ValueChanged委托似乎永远不会被调用。

这似乎是它应该是一个简单的事情,但我没能找到上线的例子,我尝试了各种组合我所能想象的。

任何想法,我应该怎么处理呢?在结合============

威尔

============附加信息被要求对不绑定的XAML信息。

如果我把这个包含用户控制页面,结合用户控件的页面视图模型:

<local:FormControl x:Name="formControl" 
     Grid.Column="2" 
     DataContext="{Binding}" 
     /> 

然后这个用户控件,绑定用户控件到窗体itemsCollection页面的viewmodel:

<telerik:RadDataForm 
     ItemsSource="{Binding itemsCollection}" 
     Header="View Item:" 
     CommandButtonsVisibility="None" 
     AutoGenerateFields="False" 
     /> 

然后一切正常。

但问题是,我无法将用户控件绑定到页面的视图模型。我需要让用户控件的视图模型公开该页面的视图模型不应该看到的信息。

而我不能让用户控件中的表单到达用户控件的外部,并绑定到页面viewmodel上的属性。这是对封装的违反,这将使得使用不同页面上的用户控件变得更加复杂,并且严重限制了我将来如何修改控件的内部。 (页面不应该知道用户控件内的任何控件,用户控件中的控件不应该知道页面的任何内容。)

当我在页面中包含用户控件时,我想绑定用户控制到页面视图模型的属性,并且我希望用户控件中的任何控件绑定到用户控件的属性或用户控件的视图模型的属性。

我认为这是一个相当常见的事件。但是我还没有找到任何可以做到的例子。

+1

Yeesh。虽然很高兴知道你是如何到达兔子洞的底部的,但我无法弄清楚为什么*你失败了。你想在你的FormControl *里面完成什么,你需要给它添加ItemsSource属性,以及你想要在你的UserControl中使用该对象做什么? – Will 2012-02-28 18:17:58

+0

FormControl包含一个窗体,并且该窗体具有一个ItemsSource属性。我想要宣传该属性,以便当我将FormControl放在页面上时,我绑定到FormControl上的属性,而不是伸入控件并绑定到其中的某个东西。 (得墨忒耳法)。 – 2012-02-28 19:12:01

+0

你试图将所有东西绑定在一起,绑定不起作用但是我不认为有人可以说,因为你添加了所有的东西,除了你希望工作的绑定没有的xaml。 – Will 2012-02-28 19:13:16

回答

3

重申问题:我有一个UserControl,它包含一个嵌入式Telerik DataForm控件。我需要将嵌入式DataForm的ItemsSource属性绑定到放置我的UserControl的页面的DataContext属性。

如果UserControl没有设置它的DataContext,它会继承页面的DataContext,并且我可以很容易地将嵌入的DataForm的ItemsSource属性绑定到它的属性,但UserControl有它自己的DataContext。

如果UserControl被编写为仅用于此页面,则可以使用RelativeSource绑定将嵌入的DataForm的ItemsSource属性绑定到页面的一个属性。但是,此用户控件旨在用于许多地方,并且不能对用户控件之外的属性进行无声依赖。我需要明确依赖。

在UserControl上创建DependencyProperty是正确的方法,但不需要尝试复制UserControl的视图模型中的属性。

我需要做的是

1:一个DependencyProperty添加到该用户控件:

public QueryableCollectionView ItemsSource 
{ 
    get { return (QueryableCollectionView)GetValue(ItemsSourceProperty); } 
    set { SetValue(ItemsSourceProperty, value); } 
} 
public static readonly DependencyProperty ItemsSourceProperty = 
    DependencyProperty.Register("ItemsSource", typeof(QueryableCollectionView), typeof(FormControl)); 

注:我并不需要实现一个回调函数。

2:绑定嵌入式的DataForm的ItemsProperty到该用户控件的这个新的DependencyProperty,使用的RelativeSource绑定:

<UserControl 
     ...> 
    <telerik:RadDataForm 
     ItemsSource="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" 
     /> 
</UserControl> 

3:请在页面视图模型可见,用适当的类型(DataContext的具有类型的对象) :

public partial class MainWindow : Window 
{ 
    public MainWIndow() 
    { 
     this.InitializeComponent(); 
     this.DataContext = new MainWindowVM(); 
    } 
    public MainWindowVM viewModel 
    { get { return this.DataContext as MainWindowVM; } } 
} 

4:在页面上,绑定用户控件的新ItemsProperty的DependencyProperty到页面视图模型的相应属性,再次使用的RelativeSource绑定:

<Window 
     ...> 
    <local:FormControl 
     ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadPane}},Path=viewModel.items}" 
     /> 
</Window> 
+0

+1对于RelativeSource = {RelativeSource AncestorType = {x:Type UserControl}} – 2013-02-20 20:50:46