2011-08-04 33 views
0

我试图通过将数据绑定到viewmodel(视图的datacontext)属性来更新视图上的文本块。如何将数据绑定到源不同于路径的CLR对象

在下面的代码中;当SelectedItem的变化,我想的名称更改文本块文本名称财产SelectedItem

在试图做到这一点我已经设置了绑定源到正在更改属性和绑定路径我想要更新与文本块中的数据。

I.e.我期待绑定引擎将看到绑定源(SelectedItem)的变化,并从绑定路径(SelectedItem.Name)拉数据。

http://msdn.microsoft.com/en-us/library/ms746695.aspx

设置selectedItem提高INPC但文字不更新。

public class ViewModel 
{ 
    public IConfiguration Configuration { get; set;} 
} 

public class Configuration : IConfiguration, INotifyPropertyChanged 
{ 
    public Item SelectedItem 
    { 
     get { return _item;} 
     set 
     { 
      _item = value; 
      ItemName = _item.Name; 
      RaisePropertyChangedEvent("SelectedItem"); 
     } 
    } 

    public string ItemName 
    { 
     get { return _itemName;} 
     set 
     { 
      _itemName= value; 
      RaisePropertyChangedEvent("ItemName"); 
     } 
    } 
} 

public class Item 
{ 
    public string Name { get; set;} 
} 

我知道,对配置变化被认为是因为这个作品:

<TextBlock Text="{Binding Configuration.ItemName}"/> 

但这并不:

<TextBlock Text="{Binding Path=Name, Source=Configuration.SelectedItem}"/> 

而且也没有这样的:

<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name, Source=Configuration.SelectedItem}"/> 

我假设这应该是str aightforward - 我错过了什么?

+0

对于第二个和第三个选项工作,你必须实现你的项目类INotifyPropertyChanged接口,以及...如果这是不可能的,那么你必须提高BindingExpression.UpdateTarget()每个Item.Name更新时间打电话在你的代码中,由于MVVM的限制,这必须在附加的行为中完成。 –

回答

0

这可能是工作,你只是看不到它。绑定引擎尚未被通知Item对象的Name属性已更改。

尝试实施的项目类INotifyPropertyChanged接口,以及(筹集必要的PropertyChanged事件)

这会为你的第三接合情况下工作,也是一个类似的定义如下

<TextBlock DataContext="{Binding Path=Configuration.SelectedItem}" Text="{Binding Path=Name}"/> 

但对于一个简单的修复,这应该工作:

<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name}" /> 

编辑:

public class Configuration : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #endregion 

    private Item _SelectedItem = null; 
    public Item SelectedItem 
    { 
     get 
     { 
      return _SelectedItem; 
     } 
     set 
     { 
      _SelectedItem = value; 
      OnPropertyChanged("SelectedItem"); 
     } 
    } 
} 

public class Item 
{ 
    public string Name { get; set; } 
} 

然后在命令执行的地方我有这样的:

Configuration.SelectedItem = new Item() { Name = "test" }; 

和视图中的细更新的TextBlock:

<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name}" /> 
+0

不幸的是Item对象在另一个程序集中不能被改变来实现INPC。但是在任何情况下,我都将Source指定为Configuration.SelectedItem,以便绑定引擎在更改时执行某些操作。也许我误解了Source的使用。 – Kildareflare

+0

你为什么试图使用绑定的Source属性?我的代码示例应该在“SelectedItem更改;更新TextBlock”的情况下工作。然而,这不适用于“Item.Name更改;更新TextBlock”,但它似乎并不像您需要此功能。 (更新与工作代码示例) – fatty

3

我从来没有真正看到任何人以前使用Binding.Source,所以我不太了解它。但我的猜测是,它不是动态的。在创建绑定时,它会抓取对源中指定的对象的引用,然后就是这样:它在绑定的整个生命周期中使用相同的引用。

为什么使这变得复杂?只需使用Path。这是进行绑定的正常方式,并且它始终是动态的 - 您正在执行的操作正是Path的目标。

<TextBlock Text="{Binding Path=Configuration.SelectedItem.Name}"/> 
+0

但这只会在“名称”实现INPC,对不对? – Kildareflare

+0

不,它仍然会绑定,如果“名称”发生更改,您将不会收到通知。当“SelectedItem”更改时,TextBlock仍将更新。 – fatty

相关问题