0

私は他の誰かによって書かれた大規模なコード プロジェクトに取り組んでいるので、できるだけ影響を与えないように変更を加えようとしています。これは、私の前任者が自分で作成したクラスである 1 つに結合されSystem.Windows.Controls.DataVisualization.Toolkitた複数の折れ線グラフを作成するために使用します。LineSeriesMultiChart

線はすべて同じ色です。色違いでお願いしました。または実際には複数の色。行数は一定ではないので、色のリストをループしたいと思っていました。次に、ほとんどのケースをカバーするのに十分な大きさを作成するだけです。

行番号に一貫性がないため、各色を明示的に定義することはできません。さらに、 には複数のデータ ポイントであるプロパティがあり、ViewModel へのバインディングを介して設定さ れMultiChartますSeriesSourceObservableCollectionLineSeriesObservableCollection

そのため、色を xaml の外部の値にバインドする必要があると思います。ビュー関連の作業であるため、コード ビハインドが色の変更に有効な場所になると思いますが、そこで機能するソリューションを見つけることができませんでした。

私はSOや他の場所で多くの質問を見てきましたが、MVVMパターンを考慮してもしなくても、どれもうまくいきませんでした。私はMVVMに作り直すことができる実用的なソリューションを探していますが、それが良い習慣でもある場合はボーナスポイントです。

私はしばらくの間 WPF を使用してきましたが、何らかの理由でデータ バインディングについて完全に理解することができません。それにもかかわらず、私はこれに近づいたと思います:

<UserControl.Resources>

<local:LocalColorConverter x:Key="MyColorConverter"/>

<Style x:Key="dataPointStyle" TargetType="{x:Type charting:LineDataPoint}">
        <Setter Property="Background" Value="{Binding Path=DataContext.ColorCount, 
                                              RelativeSource={RelativeSource AncestorType=local:MultiChart, Mode=FindAncestor}, 
                                              Converter={StaticResource MyColorConverter}}"/>
</Style>

LocalColorConverter.cs

class LocalColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int count = (int)value;
        //SolidColorBrush returnBrush = new SolidColorBrush();
        SolidColorBrush color = new SolidColorBrush();
        switch (count % 5)
        {
            case 0:
                color.Color = Colors.Blue;
                break;
            case 1:
                color.Color = Colors.Green;
                break;
            case 2:
                color.Color = Colors.Red;
                break;
            case 3:
                color.Color = Colors.Purple;
                break;
            case 4:
                color.Color = Colors.Yellow;
                break;
        }
        return color;
    }

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

これは実際にはあまり良くないことを理解しています。これは、ビューに関連する情報であるビューモデルの ColorCount 値に依存しています。悪いMVVMですが、パターンに合わせる前に動作させようとしています。

また、 は変更されないため、そのままでは機能しませんColorCount。ビューモデルでは、最初は 0 に設定されています。このパスを続行する場合は、ColorCount の値をインクリメントして、Converter が使用されるたびに色が変わるようにします。

((int)value)++コンバーターが戻る前にやってみましたが、うまくいきませんでした。そうなるとは思いませんでしたが、私が探しているもののアイデアが得られます。

それ以外の場合、私の最善の解決策は、コードビハインドでこの操作を行うことだと思います。しかし、どこで/どのようにそれを行うのかわかりません。UserControlが新しいになったら、色を変更する必要がありLineSeriesます。現在の分離コードにはLineSeries_Loadedイベント ハンドラーが実装されていますが、色は線に設定されておらず、線の各ポイントに設定されています。したがって、各行でカラーカウンターをインクリメントし、各ポイントでカウントを使用して色を決定する必要があります。

これを試しましたが、この方法で Background プロパティを見つけることができないようです。MultiChartchart はオブジェクトに付けられた名前であることに注意してください。

private void LineSeries_Loaded(object sender, RoutedEventArgs e)
    {
        foreach(LineSeries line in chart.Series.Cast<LineSeries>())
        {
            foreach(LineDataPoint point in line)
            {

            }
        }
    }

しかし、行に public GetEnumerator がないというエラーが表示されます。

助言がありますか?

4

1 に答える 1

0

ええと、質問を書いたことで私の創造力が湧いてきました。コードビハインドでスタイルセッターを設定しようとしたことを思い出しましたが、ロード時にスタイルを変更することはできません。しかし、いつでもスタイルを切り替えることができることに気付きました。だから私はこれらを作った:

<Style x:Key="blueDataPointStyle" TargetType="{x:Type charting:LineDataPoint}" BasedOn="{StaticResource dataPointStyle}">
    <Setter Property="Background" Value="Blue"/>
</Style>

<Style x:Key="redDataPointStyle" TargetType="{x:Type charting:LineDataPoint}" BasedOn="{StaticResource dataPointStyle}">
    <Setter Property="Background" Value="Red"/>
</Style>

<Style x:Key="greenDataPointStyle" TargetType="{x:Type charting:LineDataPoint}" BasedOn="{StaticResource dataPointStyle}">
    <Setter Property="Background" Value="Green"/>
</Style>

次に、コード ビハインドで次のようにします。

private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        int count = 0;
        foreach (LineSeries line in chart.Series)
        {
            switch (count % 3)
            {
                case 0:
                    line.DataPointStyle = Resources["blueDataPointStyle"] as Style;
                    break;
                case 1:
                    line.DataPointStyle = Resources["redDataPointStyle"] as Style;
                    break;
                case 2:
                    line.DataPointStyle = Resources["greenDataPointStyle"] as Style;
                    break;
            }
            count++;

        }
    }

それは働いている!ほとんどの場合、他のすべての行が 1 つにグループ化されていることが判明したので、まだやるべきことがいくつかあります。しかし、これは私が尋ねたことに対する答えです。さらに、MVVMに適合するようです。バインディングは必要ないことがわかりました(おそらく、それを思いついた理由です)。しかし、私はまだ他のアイデアに興味があります。適切なバインディングの例が欲しいです。

于 2015-11-16T19:14:21.733 に答える