2012-04-20 37 views
6

Tôi có UserControl của riêng mình, một LabeledTextBox là sự kết hợp của Label và a..well, TextBox. Điều khiển này có hai thuộc tính: Caption sẽ được gắn với chú thích của LabelValue sẽ được gắn với Text của số TextBox.Làm thế nào để sử dụng TwoWay ràng buộc từ bên trong một UserControl?

Code:

public class LabeledTextBox : Control 
{ 
    static LabeledTextBox() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(LabeledTextBox), new FrameworkPropertyMetadata(typeof(LabeledTextBox))); 
    } 

    public string Caption 
    { 
     get { return (string)GetValue(CaptionProperty); } 
     set { SetValue(CaptionProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Caption. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty CaptionProperty = 
     DependencyProperty.Register("Caption", typeof(string), typeof(LabeledTextBox), new UIPropertyMetadata("")); 


    public string Value 
    { 
     get { return (string)GetValue(ValueProperty); } 
     set { SetValue(ValueProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty ValueProperty = 
     DependencyProperty.Register("Value", typeof(string), typeof(LabeledTextBox), new UIPropertyMetadata("")); 


} 

XAML:

<Style TargetType="{x:Type local:LabeledTextBox}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:LabeledTextBox}"> 
       <Grid> 
        <Grid> 

        <Grid.RowDefinitions> 
         <RowDefinition /> 
         <RowDefinition /> 
        </Grid.RowDefinitions> 

        <Label Grid.Row="0" Content="{TemplateBinding Caption}" /> 
        <TextBox Name="Box" Margin="3,0,3,3" Grid.Row="1" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" /> 

        </Grid> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Cách sử dụng:

<uc:LabeledTextBox Caption="Code:" Value="{Binding ExpenseCode}" /> 

Ban đầu tôi nghĩ rằng tôi đã tìm thấy câu trả lời của tôi ở đây: WPF TemplateBinding vs RelativeSource TemplatedParent

Đó chi tiết differen ce giữa TemplateBindingRelativeSource TemplatedParent. Tôi đã thay đổi mã của tôi cho phù hợp, nhưng nó vẫn cảm thấy như tôi đang thiếu một bước. Liên kết OneWay hoạt động, hộp văn bản của tôi bị ràng buộc với thuộc tính Giá trị, nhưng các thay đổi không được đăng ký.

Tôi làm cách nào để hoạt động?

+0

Bạn đã thử làm cho thuộc tính Giá trị phụ thuộc của bạn HaiWay là tốt? Hoặc là vấn đề mà TextBox không viết vào giá trị dp của bạn? – dowhilefor

+0

Có phải 'LabeledTextBox.Value' không thay đổi hoặc là' ExpenseCode' trong đối tượng dữ liệu không? Bạn có thể thêm một [PropertyChangedCallback] (http://msdn.microsoft.com/en-us/library/system.windows.propertychangedcallback.aspx) vào thuộc tính 'Value' dependency để xem nó có được gọi hay không. – Clemens

+0

@dowhilefor: đó không phải là những gì 'Mode = TwoWay' trong XAML là cho? @Clemens: Ban đầu tôi đã có cuộc gọi lại đó và nó đã được gọi. Trong cuộc gọi lại đó, tôi đặt giá trị của hộp văn bản. Tôi có cần phải rõ ràng làm cho dữ liệu quay trở lại từ bên trong DP không? @Ricibob: cảm ơn, nhưng điều đó dường như không đúng. – diggingforfire

Trả lời

6

Thay đổi chế độ tại đây.

<uc:LabeledTextBox Caption="Code:" Value="{Binding ExpenseCode,Mode=TwoWay}" /> 

nó làm việc ở cuối của tôi

+0

Tuyệt vời, đã làm các trick! – diggingforfire

+1

Tôi đã thử tất cả các kết hợp có thể có của chế độ theo kiểu n khai báo. @ dowhile là đúng, cảm ơn cho giải thích :) – Akanksha

+0

Tôi không hoàn toàn là một WPF chuyên nghiệp, nhưng đó là một cách tiếp cận tốt :) – diggingforfire

4

Chỉ trong trường hợp bất cứ ai có vấn đề này:

cách tiếp cận khác (có thể thêm thanh lịch) sẽ được tuyên bố thuộc tính phụ thuộc của usercontrol một cách để nó mặc định để ràng buộc hai chiều (ví dụ như khung TextBox làm theo mặc định).

này có thể đạt được như sau (lấy từ câu trả lời của this Stackoverflow question):

public DependencyProperty SomeProperty = 
     DependencyProperty.Register("Some", typeof(bool), typeof(Window1), 
      new FrameworkPropertyMetadata(default(bool), 
       FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

Mấu chốt ở đây là sử dụng FrameworkPropertyMetadata.

Các vấn đề liên quan