0

C# で WPF アプリケーションを作成しています。このアプリケーションは、MVVM を使用して設計されています。

現在、いくつかのチェックボックスを備えた親ウィンドウがあります。ユーザーは、必要なボックスにチェックを入れてから、「プロット」をクリックできますButton。「プロット」をクリックすると、新しい子ウィンドウが表示され、単一のグラフにデータが表示されます。

したがって、チェック ボックスを 1 つだけオンにして [プロット] をクリックすると、1 本の線が表示されたグラフが表示されます。2 つのチェック ボックスをオンにして [プロット] をクリックすると、同じ 1 つのグラフが表示されますが、2 本の線が表示されます。

私の現在の実装:

現在、私はと呼ばれる「ビュー」クラスを持っていますGraphWindowView。ビューは明らかに、どのデータを表示するかを知る必要があります。そのために、私は依存関係プロパティを持っておりGraphWindowView.Dates、どの究極が(y 軸) 対(x 軸)GraphWindowView.Dataのグラフを生成します。DataDates

質問:のこの現在の実装は明らかに 1 セットのデータ (対)GraphWindowViewをグラフ化できるように制限されています。これを (かなり) 拡張可能にして、チェック ボックスがどれだけチェックされているかに応じて、任意の数のプロットを利用できるようにしたいと考えています。どうすればこれを行うことができますか?依存関係プロパティの使用を再考する必要があると思います...DataDates

>>> 更新

そこでGraphLine、グラフ上の線を表すクラスを作成しました。「グラフ」は実際にはクラスのChartPlotter要素です。また、オブジェクトにGraphWindowPresenter.xamla を指定しDataTypeましたが、それは私が理解しているすべてです。GraphLineこれに対する次のステップは何ですか?実際にデータをグラフに追加するにはどうすればよいですか? GraphLineそして、要素を設定するためにどのように/どこでインスタンスを作成しますChartPlotterか? 申し訳ありませんが、かなりの数のチュートリアルを読んだ後でも、これについてはかなり迷っています。これまでご協力いただきありがとうございました。本当に感謝しています。

GraphWindowView.xaml

<Window x:Class="BMSVM_Simulator.View.GraphWindowView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ViewModel="clr-namespace:BMSVM_Simulator.ViewModel"
        xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"
        x:Name="ThisGraphWindowInstance"
        Title="Plot" Height="500" Width="750"
        Icon="../res/qualcomm_q_icon.ico.ico"
        MinWidth="400" MinHeight="300">

    <Window.DataContext>
        <ViewModel:GraphWindowPresenter/>
    </Window.DataContext>

    <d3:ChartPlotter Name="plotter" Margin="10,10,20,10">
        <d3:ChartPlotter.HorizontalAxis>
            <d3:HorizontalIntegerAxis Name="dateAxis"/>
        </d3:ChartPlotter.HorizontalAxis>
        <d3:ChartPlotter.VerticalAxis>
            <d3:VerticalIntegerAxis Name="countAxis"/>
        </d3:ChartPlotter.VerticalAxis>

        <d3:Header FontFamily="Arial" Content="{Binding ElementName=ThisGraphWindowInstance, Path=title}"/>
        <d3:VerticalAxisTitle FontFamily="Arial" Content="{Binding ElementName=ThisGraphWindowInstance, Path=yAxis}"/>
        <d3:HorizontalAxisTitle FontFamily="Arial" Content="{Binding ElementName=ThisGraphWindowInstance, Path=xAxis}"/>
    </d3:ChartPlotter>

    <Window.Resources>
        <DataTemplate DataType="{x:Type ViewModel:GraphLine}">
            <!--WHAT GOES HERE-->
        </DataTemplate>
    </Window.Resources>

</Window>

GraphLine.cs

namespace BMSVM_Simulator.ViewModel
    {
        class GraphLine
        {
            public string xAxis                     { get; private set; }
            public string yAxis                     { get; private set; }
            public string title                     { get; private set; }
            public string legend                    { get; private set; }
            public EnumerableDataSource<int> data   { get; private set; }
            public EnumerableDataSource<int> dates  { get; private set; }
        }
    }
4

1 に答える 1

2

DataTemplateWPF でのこれらのタイプの問題のほとんどは、何マイルもの手続き型コードではなく、データ バインディングと を注意深く使用することで解決できます。一般的な考え方は、すべての線を描画するために必要なすべてのプロパティを持つカスタム クラスを作成することです。次に、 を宣言しDataTemplateて、さまざまなプロパティをデータ バインドする方法を定義します。おそらく次のようになります。

<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:GraphLine}">
    <Line X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X2}" Y2="{Binding Y2}" />
</DataTemplate>

次に、カスタム クラス インスタンスのコレクションを作成し、それを のようなコレクション コントロールにデータ バインドするItemsControlと、それぞれが正しい場所に自動的にレンダリングされます。

<ItemsControl ItemsSource="{Binding YourGraphLineCollection, RelativeSource={
    RelativeSource AncestorType={x:Type YourXamlNamespacePrefix:YourControlName}}}" />

DataTemplateWPF データ バインディングとs の強力な世界へようこそ。


更新 >>>

Line要素にデータ バインドするカスタム クラスはビュー モデルではありません。上記のような を宣言するデータ型クラスと考えてくださいDataTemplate。必要なすべてのプロパティが必要であると言ったとき、上記の例を見るとdouble、要素の 4 つの使用済みプロパティにデータ バインドするには、少なくとも 4 つのプロパティが必要であることがわかりますLine。ただし、たとえばStrokeStrokeThicknessまたはプロパティにデータ バインドするために、さらにプロパティを追加することもできます。Fill

を定義する場所についてはDataTemplate、それが適用されているアイテムの範囲内にある必要があります。1 つのビューで使用する場合は、UserControl.Resourcesそのビューのセクションに配置します。ただし、同じ を使用する場合は、アプリケーション全体で使用できるため、ファイルのセクションにDataTemplate配置する必要があります。Application.ResourcesApp.xamlResources


最終更新 >>>

私のコメントで述べたように、ユーザーに WPF の使用方法を教えることは、この Web サイトの範囲外であるため、私はそれを行いません。について学習するDataTemplateには、MSDN のデータ テンプレートの概要ページを参照してください。不明な点がある場合は、常にMSDNで回答を検索してください。

先に進む前に、いくつかの最後のヒントをお伝えできDependencyPropertyます。コントロール内の は 型である必要がありますObservableCollection<GraphLine>ItemsControlコントロール内では、上記のようにデータを何らかの種類にバインドする必要があります-状況でプロパティを見つけるためにBinding Path実際に a を使用する必要があるため、変更しました (オブジェクトを描画する場所の名前はどこですか) .RelativeSource BindingYourControlNameUserControlLine

最後に、ビュー モデル (線を描画する new を含むビューにリンクされている) では、のUserControlコレクションとデータ バインドするためのコレクション プロパティが必要です。UserControlYourGraphLineCollectionInViewModel

<YourXamlNamespacePrefix:YourControlName YourGraphLineCollection="{Binding 
    YourGraphLineCollectionInViewModel}" />

GraphLineクラスのインスタンスをコレクションに追加するのはこのビュー モデルであり、ここに示すようYourGraphLineCollectionInViewModelに を設定している限りBinding Path、それらは 内の UI に表示されますItemsControl。正しく設定する方法を知っていることを前提としていますDataContext。そうでない場合は、オンラインで簡単に見つけることができます。

于 2014-06-10T11:22:22.223 に答える