2013-12-18 6 views
2

나는 다음과 같은 시나리오가 :WinRT XAML 데이터 바인딩

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

내의 ViewModel의 ObservableCollection에를 만들고 해당 뷰 모델에 HubPage에 DataContext를 설정합니다.

내 HubPage에는 TestUserControl이라는 간단한 UserControl이 있습니다. 해당 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> 

UserControl을 코드 ​​뒤에 : 내 UserControl을이 HubModel을 알고 있어야하기 때문에

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

나는 DependencyProperty를 통해 TextBlock의 텍스트 경로를 결합 싶어요. HubPage에서

XAML :

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

컬렉션 = "{을 TestCollection 바인딩}"내 UserControl을에서 DependencyProperty에 목록을 설정합니다.

Text = "Name"은 속성 이름을 설정합니다. 계획은 내 UserControl이 TextBlock Text "Name"에 대해 DependencyProperty를 찾고 바인딩 된 클래스 HubModel에서 속성 "Name"의 값을 가져 오는 것입니다.

내 UserControl은 DependencyProperty에서 "Name"을 찾고 클래스의 속성 값 대신 컬렉션의 모든 항목에 대해 "Name"을 표시합니다.

이렇게 할 수 있나요? 또는 UserControls 내에서 바인딩하는 가장 좋은 방법은 무엇입니까. 내 옵션에서 바인딩 된 클래스의 속성 이름을 알 수 없습니다.

감사 다니엘

답변

1

여기에 까다로운 부분은 본질적으로 Binding 자체 (즉 Binding.Path)의 속성을 결합하기 위해 노력하고 있다는 점이다. Binding은 DependencyObject가 아니기 때문에 가능하지 않으며 Binding.Path은 종속성 속성이 아닙니다. 그래서 당신은 뒤로 물러나서 다른 접근법을 찾아야합니다.

하나 (대상물이 경우, "HubModel"에 대한)를 첨가 종속성 속성 SourceObjectTextBlock의 서브 클래스를 생성 할 수 있으며, PropertyName 것, 또는 유사한 (속성은 "이름"을 표시하기 위해). 그러면 리플렉션을 사용하여 Text을 업데이트 할 수 있습니다.

그래서 당신이 대신 TextBlock을 작성합니다

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()); 
    } 
} 

(이에 대한 MultiBinding을 사용하지만, 수 WPF에서 그 존재하지 않습니다

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

그리고 ExtendedTextBlock은 다음과 같이 보일 것입니다 지금까지 WinRT에서 알고 있습니다.)