2012-05-16 2 views
0

내 WPF 응용 프로그램의 양식에서 psuedo 막대 그래프를 작성하고 있습니다. 막대 그래프는 12 개의 열이있는 격자로 구성됩니다. 각 열은 사각형을 포함합니다. 나는 데이터 바인딩을 사용하여 사각형의 높이를 그래프에 바인딩 할 데이터에 바인딩합니다. xaml은 다음과 같습니다.왜 멀티 바인딩은 항상 첫 번째 값에 대해 DependencyProperty.UnsetValue를 전달합니까?

<Border BorderBrush="{DynamicResource ControlBorder}" 
     BorderThickness="2" 
     Grid.Column="1" 
     Grid.Row="0" 
     Margin="0,5" 
     Name="SNRGraphBorder"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Rectangle Fill="{DynamicResource TextForeground}" 
        Grid.Column="0" 
        Margin="1,5,2,0" 
        Name="Data01" 
        VerticalAlignment="Bottom"> 
      <Rectangle.Height> 
       <MultiBinding Converter="{StaticResource ScaleData}"> 
        <Binding Source="{StaticResource XmlProvider}" 
          XPath="a:PathToData}" /> 
        <Binding Path="RectangleHeight" 
          RelativeSource="{RelativeSource AncestorType={x:Type cs:MyControl}}" /> 
       </MultiBinding> 
      </Rectangle.Height> 
     </Rectangle> 
     . . . 
    </Grid> 
</Border> 

간략하게하기 위해 하나의 직사각형 만 포함했습니다. 여기

이 MultiBinding에 사용되는 IMultiValueConverter에 대한 코드입니다 :

public partial class MyControl : UserControl { 

    public XmlDataProvider DataProvider { get; set; } 

    public DeviceMonitor DeviceMonitor { get; set; } 

    public double RectangleHeight { 
     get { return SNRGraphBorder.ActualHeight; } 
    } 

    public MyControl() { 
     InitializeComponent(); 
     DataProvider = Resources[ "XmlProvider" ] as XmlDataProvider; 
    } 

    private void GetDiagnosticsInfo() { 
     if (DeviceMonitor != null) { 
      XmlDocument diagnosticsDoc = new XmlDocument(); 
      string info = DeviceMonitor.GetDiagnosticInfo(); 
      diagnosticsDoc.LoadXml(info); 
      DataProvider.Document = diagnosticsDoc; 
     } 
    } 

    private void RefreshButton_Click(object sender, RoutedEventArgs e) { 
     GetDiagnosticsInfo(); 
     e.Handled = true; 
    } 
} 

나는 if (values[ 0 ] is string)에 컨버터에 중단 점을 넣어했습니다 마지막으로

public class ScaleDataConverter : IMultiValueConverter { 

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 
     double snr = 0.0; 

     if (values[ 0 ] is string) { 
      snr = double.Parse(values[ 0 ] as string); 

     } else if (values[ 0 ] is int || values[ 0 ] is double || values[ 0 ] is long || values[ 0 ] is float) { 
      snr = (double) values[ 0 ]; 
     } else { 
      return values[ 0 ]; 
     } 

     double ActualHeight = (double) values[ 1 ]; 
     return snr * ActualHeight/99.0; 
    } 

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

} 

, 여기에 코드는이 컨트롤 뒤에 선. 값 배열의 첫 번째 항목은 항상 DependencyProperty.UnsetValue입니다. 그러나 XML에이 속성에 대한 다른 데이터가 있다는 것을 알고 있습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

감사

토니

+0

"XmlProvider"키가있는 XmlDataProvider를 Resources에 추가 했습니까? 그리고 "a : PathToData}"가 맞습니까? 하나의 대괄호입니까? – RredCat

+0

예, "XmlProvider"키가있는 XmlDataProvider를 Resources에 추가했습니다. 나는 그 예에서 그것을 보여주지 않았다. 내 XPath는 정확합니다. 이전 버전의 IMultiBinding 및 IMultConverter가없는 이전 버전의 코드가 있었으며이 버전의 데이터를 볼 수있었습니다. 문제는 IMultiConverter를 호출 할 때마다 첫 번째 매개 변수가 항상 DependencyProperty.UnsetValue라는 것입니다. –

+0

hm .. 흥미로운 .. 'IMultiValueConverter'에서 'RectangleHeight'의 값이 올바른가요? – RredCat

답변

1

나는 문제를 해결 할 수있었습니다. 첫 번째 멀티 바인딩에서 XPath를 자세히 살펴보면 "}"로 끝나는 것을 볼 수 있습니다. 그 문자는 실제로 XPath의 일부가 아니며 {Binding Source = {...} XPath = ....} 구문을 사용하는 단일 바인딩 일 때 바인딩의 원래 텍스트에서 남은 것입니다. 일단 제거하면 값 배열의 첫 번째 값으로 DependencyProperty.UnsetValue이 중지됩니다.

두 번째 값이 0 인 다른 문제도 해결할 수있었습니다. RectangleHeight 속성을 DependencyProperty으로 만들고 Loaded 이벤트 처리기에 코드를 추가하여 Rectangles이 모두 포함 된 Grid 컨트롤의 실제 높이와 같게 설정했습니다. 이제 내 코드가 작동하고 멋진 막대 그래프가 나타납니다.

고맙습니다.

+0

또한 SizeChanged 이벤트에서 RectangleHeight를 설정하는 코드를 추가하십시오. – RredCat

+0

좋은 점! 고마워, 나는 그걸 생각하지 않았다. –

+0

RelativeSource 바인딩을 사용하는 경우에만 모든 일이 끝난 후에 똑같은 일이 일어났습니다. 내 RelativeSource 바인딩의 구문이 잘못되었는지 확인했지만 Path의 구문을 확인하지는 않았습니다. 마지막에 여분의}를 없앰으로써 마침내 문제가 해결되었습니다. –

관련 문제