2013-06-07 37 views
9

Tôi đã tạo một UserControl với một số DependencyProperties (trong ví dụ ở đây chỉ có một thuộc tính chuỗi). Khi tôi khởi tạo Usercontrol, tôi có thể thiết lập thuộc tính của UserControl và nó được hiển thị như mong đợi. Khi tôi cố gắng thay thế văn bản tĩnh bằng Binding, không có gì được hiển thị.Ràng buộc với UserControl DependencyProperty

My UserControl trông như sau:

<User Control x:Class="TestUserControBinding.MyUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="30" d:DesignWidth="100"> 
    <Grid> 
    <Label Content="{Binding MyText}"/> 
    </Grid> 
</UserControl> 

Bộ luật Đằng sau là:

namespace TestUserControBinding { 

    public partial class MyUserControl : UserControl { 
    public MyUserControl() { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

    public static readonly DependencyProperty MyTextProperty = 
        DependencyProperty.Register(
         "MyText", 
          typeof(string), 
          typeof(MyUserControl)); 

    public string MyText { 
     get { 
     return (string)GetValue(MyTextProperty); 
     } 
     set { 
     SetValue(MyTextProperty, value); 
     } 
    }// MyText 

    } 
} 

Khi tôi cố gắng này trong MainWindow của tôi, mọi thứ đều như mong đợi:

<Window x:Class="TestUserControBinding.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestUserControBinding" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
    <local:MyUserControl MyText="Hello World!"/> 
    </StackPanel> 
</Window> 

Nhưng điều này không hoạt động:

<Window x:Class="TestUserControBinding.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestUserControBinding" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
    <local:MyUserControl MyText="{Binding Path=Text}"/> 
    <Label Content="{Binding Path=Text}"/> 
    </StackPanel> 
</Window> 

Hành vi của nhãn là chính xác, vì vậy không có vấn đề với "Văn bản" tài sản

sai lầm của tôi là gì? Tôi suy nghĩ nhiều giờ, nhưng không thể tìm thấy bất cứ điều gì tôi đã quên.

Trả lời

10

Với sự ràng buộc sau trong UserControl của bạn:

<Label Content="{Binding MyText}"/> 

Tôi không chắc chắn cách thiết lập các văn bản trực tiếp đến các công trình bất động sản MyText. Bạn phải đặt DataContext trên UserControl ở đâu đó để thiết bị này hoạt động.

Bất kể, ràng buộc này là vấn đề - vì tôi hiểu kịch bản của bạn, bạn không muốn liên kết với DataContext của UserControl vì điều đó sẽ không nhất thiết phải có thuộc tính MyText. Bạn muốn liên kết với chính số UserControl và cụ thể là DependencyProperty bạn đã tạo. Để làm điều đó, bạn cần phải sử dụng một RelativeSource ràng buộc, như sau:

<Label Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}}, Path=MyText}"/> 

này sẽ di chuyển lên cây thị giác để MyUserControl và sau đó tìm tài sản MyText đó. Nó sẽ không phụ thuộc vào DataContext, sẽ thay đổi dựa trên nơi bạn đặt UserControl.

Trong trường hợp này, local đề cập đến một không gian tên bạn sẽ cần phải xác định trong UserControl:

<UserControl x:Class="TestUserControBinding.MyUserControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:TestUserControBinding" 
     ...> 

Và ví dụ thứ hai của bạn nên làm việc tại thời điểm đó.

+0

@Brian ... Mã "this.DataContext = this;" nên chú ý đến việc thiết lập DataContext thành cục bộ. Phải không? – Nishant

+4

Ồ, vâng, tôi đã bỏ lỡ điều đó. Nhưng nếu bạn đang tạo một 'UserControl', tôi không nghĩ rằng bạn nên đặt' DataContext' theo cách thủ công. 'DataContext' được thiết kế để đại diện cho bối cảnh được kế thừa hoặc được gán từ vùng chứa. Liên kết 'RelativeSource' cho phép bạn đạt được kết quả mong muốn (liên kết với' DependencyProperty') trong khi không làm gián đoạn luồng thừa kế 'DataContext' chuẩn. Cố gắng ghi đè lên 'DataContext' như bạn sẽ thất bại nếu người dùng' UserControl' của bạn đặt 'DataContext' của riêng họ. –

+2

đó chính xác là vấn đề.Thay vì thiết lập DataContext của MyUserControl thành chính tôi bây giờ tôi sử dụng 'x: Name =" MyName "' trong thẻ mở của 'MyUserControl' và các thay đổi Binding thành:'