2013-12-18 6 views
2

У меня есть следующий сценарий:WinRT XAML DataBinding

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

я создать ObservableCollection в моей ViewModel и установить DataContext на HubPage к этому ViewModel.

На моей странице HubPage у меня есть простой UserControl, называемый TestUserControl.

XAML из UserControl:

<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> 

код 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)); 

Потому что мой UserControl не должен знать HubModel Я хочу связать TextBlock Text-Path через DependencyProperty.

XAML из HubPage:

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

Collection = "{Binding TestCollection}" задает список к DependencyProperty в моем UserControl.

Текст = "Имя" устанавливает имя свойства. План заключается в том, что мой UserControl находит для TextBlock Text «Name» в DependencyProperty и принимает значение из свойства «Имя» из связанного класса HubModel.

Проблема заключается в том, что мой UserControl находит «Имя» в DependencyProperty и показывает «Имя» для каждой записи в коллекции вместо значения свойства в классе.

Возможно ли это как можно? Или что лучше всего подходит для привязки в UserControls. В моем параметре не должно быть имени свойства из связанных классов.

Благодаря Daniel

ответ

1

Хитрость здесь в том, что вы, по сути пытается связать свойство самого Binding (а именно Binding.Path). Это невозможно, потому что Binding не является объектом DependencyObject, а Binding.Path не является свойством зависимостей. Поэтому вам нужно отступить и найти другой подход.

Можно было бы создать подкласс TextBlock, с добавлением свойств зависимостей SourceObject (для объекта «HubModel» в данном случае), и PropertyName (для свойства для отображения, «Name»), или аналогичный. Это позволит вам обновить 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, насколько я знаю.)

Смежные вопросы