0

在我的 WPF 应用程序的一个表单中,我正在构建一个伪条形图。条形图由一个 12 列的网格组成。每列包含一个矩形。我正在使用数据绑定将矩形的高度绑定到我想要绘制的数据。xaml 看起来像这样:

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

}

最后,这里是这个控件的代码:

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 )。我看到值数组中的第一个条目始终是 DependencyProperty.UnsetValue。然而,我知道 XML 有其他关于这个属性的数据。我究竟做错了什么?

谢谢

托尼

4

1 回答 1

1

我已经能够解决这个问题。如果您仔细查看第一个多重绑定中的 XPath,您会发现它以“}”结尾。该字符实际上不是 XPath 的一部分,当它是使用 {Binding Source={...} XPath=....} 语法的单个绑定时,它是绑定的原始文本的剩余部分。删除它后,我停止获取DependencyProperty.UnsetValuevalues 数组中的第一个值。

我还能够解决第二个值为零的另一个问题。我创建了 RectangleHeight 属性 aDependencyProperty并在 Loaded 事件处理程序中添加了代码,以将其设置为等于Grid包含所有Rectangles. 现在我的代码工作了,我得到了一个可爱的条形图。

谢谢所有看过的人。

于 2012-05-17T20:57:39.117 回答