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>

簡潔にするために、長方形を1つだけ含めました。

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.UnsetValue、values配列の最初の値の取得を停止しました。

2番目の値がゼロであるという別の問題も解決できました。RectangleHeightプロパティをaにし、Loadedイベントハンドラーにコードを追加して、すべてを含むコントロールDependencyPropertyの実際の高さに等しくなるように設定しました。これでコードが機能し、素敵な棒グラフが得られます。GridRectangles

見てくれたすべての人に感謝します。

于 2012-05-17T20:57:39.117 に答える