2012-04-02 20 views
8

Tôi cần phải xác định StringFormat của một số ràng buộc TextBlocks khi chạy dựa trên hệ thống đơn vị được xác định trong đối tượng sẽ bị ràng buộc.IValueConverter with Bound Dependency Properties

Tôi có trình chuyển đổi có Thuộc tính phụ thuộc mà tôi muốn Liên kết. Giá trị Ràng buộc được sử dụng để xác định quy trình chuyển đổi.

public class UnitConverter : DependencyObject, IValueConverter 
{ 
    public static readonly DependencyProperty IsMetricProperty = 
     DependencyProperty.Register("IsMetric", typeof(bool), typeof(UnitConverter), new PropertyMetadata(true, ValueChanged)); 

    private static void ValueChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     ((UnitConverter)source).IsMetric = (bool)e.NewValue; 
    } 

    public bool IsMetric 
    { 
     get { return (bool)this.GetValue(IsMetricProperty); } 
     set { this.SetValue(IsMetricProperty, value); } 
    } 

    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (IsMetric) 
      return string.Format("{0:0.0}", value); 
     else 
      return string.Format("{0:0.000}", value); 
    } 

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Tôi tuyên bố chuyển đổi

<my:UnitConverter x:Key="Units" IsMetric="{Binding Path=IsMetric}"/> 

và ràng buộc TextBlock

<TextBlock Text="{Binding Path=Breadth, Converter={StaticResource Units}}" Style="{StaticResource Values}"/> 

Không bao giờ là ít, tôi nhận được lỗi sau:

System.Windows.Data Lỗi: 2: Không thể tìm thấy khung điều chỉnh FrameworkElement hoặc FrameworkContentElement cho phần tử đích. BindingExpression: Đường dẫn = IsMetric; DataItem = null; thành phần đích là 'UnitConverter' (HashCode = 62641008); thuộc tính đích là 'IsMetric' (loại 'Boolean')

Tôi đoán đây là khởi tạo trước khi tôi đặt datacontext và do đó không có gì để ràng buộc thuộc tính IsMetric. Làm thế nào tôi có thể đạt được kết quả mong muốn?

Trả lời

6

Với điều kiện là BreadthIsMetric là tài sản của đối tượng cùng một dữ liệu, bạn có thể sử dụng một MultiBinding kết hợp với một multi value converter:

<TextBlock> 
    <TextBlock.Text> 
     <MultiBinding Converter="{StaticResource UnitMultiValueConverter}"> 
      <Binding Path="Breadth" /> 
      <Binding Path="IsMetric" /> 
     </MultiBinding> 
    </TextBlock.Text> 
</TextBlock> 

với bộ chuyển đổi như thế này:

public class UnitMultiValueConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     double value = (double)values[0]; 
     bool isMetric = (bool)values[1]; 
     string format = isMetric ? "{0:0.0}" : "{0:0.000}"; 
     return string.Format(format, value); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Vấn đề với cách tiếp cận của bạn là khi UnitConverter được khai báo là tài nguyên, nó không có DataContext, và nó sẽ không bao giờ có được một sau này.

Và một điều quan trọng nữa là: ValueChanged gọi lại cho UnitConverter.IsMetric là vô nghĩa. Nó đặt lại cùng một thuộc tính vừa được thay đổi.

+0

Tôi muốn tránh điều này vì tôi có hàng trăm TextBlocks và tôi không muốn phải trải qua và thay đổi tất cả. –

+0

Cảm ơn người đàn ông, Yea tôi nhận ra tôi đã chỉ cần thiết lập cùng một tài sản, tốt nếu nó đã từng được gọi là đó! Công trình MultiBinding Great tuy nhiên –