2013-12-18 55 views
2

我有以下情形:的WinRT XAML数据绑定

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

我创造我的ViewModel一个ObservableCollection和设置的DataContext的中心页到视图模型。

在我的HubPage上我有一个名为TestUserControl的简单UserControl。从用户控件

XAML:

<UserControl 
    x:Name="userControl" 
    ....> 
    <Grid> 
     <StackPanel Orientation="Vertical"> 
      <ItemsControl x:Name="ItemsContainer" ItemsSource="{Binding Collection}"> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <Button Margin="0,0,0,20"> 
          <StackPanel> 
           <TextBlock Foreground="Black" HorizontalAlignment="Left" FontFamily="Arial" FontSize="42" VerticalAlignment="Center" Name="CurrencyTextBlock" Text="{Binding Path=Text,ElementName=userControl}"></TextBlock> 
          </StackPanel> 
         </Button> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 
     </StackPanel> 
    </Grid> 
</UserControl> 

用户控件的代码背后:

public ObservableCollection<object> Collection 
{ 
    get { return (ObservableCollection<object>)GetValue(CollectionProperty); } 
    set { SetValue(CollectionProperty, value); } 
} 

public static readonly DependencyProperty CollectionProperty = 
    DependencyProperty.Register("Collection", typeof(ObservableCollection<object>), typeof(TestUserControl), new PropertyMetadata(null)); 


public string Text 
{ 
    get { return (string)GetValue(TextProperty); } 
    set { SetValue(TextProperty, value); } 
} 

public static readonly DependencyProperty TextProperty = 
    DependencyProperty.Register("Text", typeof(string), typeof(TestUserControl), new PropertyMetadata(string.Empty)); 

因为我的用户不应该知道HubModel我想通过绑定的DependencyProperty TextBlock的文本路径。从中心页

XAML:

... 
<userControls:TestUserControl Collection="{Binding TestCollection}" Text="Name"/> 
... 

集= “{结合为TestCollection}” 将在我的用户的列表中的DependencyProperty。

Text =“Name”设置属性名称。该计划是我的UserControl在DependencyProperty中为TextBlock Text“Name”查找并从绑定的类HubModel的Property“Name”中获取值。

问题是我的UserControl在DependencyProperty中查找“Name”,并显示集合中每个条目的“Name”而不是该类中的属性值。

是这样的可能吗?或者什么是在UserControls内进行绑定的最佳方式。在我的选择中,不应该知道绑定类中的属性名称。

感谢 丹尼尔

回答

1

这里棘手的部分是,你基本上试图将Binding本身(即Binding.Path)的属性绑定。这是不可能的,因为Binding不是一个DependencyObject,并且Binding.Path不是依赖项属性。所以你必须退后一步,找到另一种方法。

一个是创建的TextBlock一个亚类中,添加了依赖属性SourceObject(该对象在此情况下,“HubModel”),和PropertyName(用于属性来显示,“名称”),或类似的。这将允许您使用反射更新Text

所以,你会写这篇文章,而不是TextBlock

<my:ExtendedTextBlock SourceObject="{Binding}" PropertyName="{Binding Path=Text,ElementName=userControl}" /> 

而且ExtendedTextBlock会是这个样子:

public class ExtendedTextBlock : TextBlock 
{ 
    public object SourceObject 
    { 
     get { return GetValue(SourceObjectProperty); } 
     set { SetValue(SourceObjectProperty, value); } 
    } 
    public static readonly DependencyProperty SourceObjectProperty = 
     DependencyProperty.Register("SourceObject", 
      typeof(object), 
      typeof(ExtendedTextBlock), 
      new PropertyMetadata(UpdateText) 
     ); 

    public string PropertyName 
    { 
     get { return GetValue(PropertyNameProperty); } 
     set { SetValue(PropertyNameProperty, value); } 
    } 
    public static readonly DependencyProperty PropertyNameProperty = 
     DependencyProperty.Register("PropertyName", 
      typeof(string), 
      typeof(ExtendedTextBlock), 
      new PropertyMetadata(UpdateText) 
     ); 

    public static void UpdateText(object sender, DependencyPropertyChangedEventArgs args) 
    { 
     var owner = (ExtendedTextBlock)sender; 
     if (owner.SourceObject == null || string.IsNullOrEmpty(owner.PropertyName)) 
      return; 

     var prop = SourceObject.GetType().GetProperty(PropertyName); 
     if (prop == null) 
      return; 

     var val = prop.GetValue(SourceObject, null); 
     owner.Text = (val == null ? "" : val.ToString()); 
    } 
} 

(在WPF中你可以使用MultiBinding这一点,但不存在在WinRT中据我所知。)