4

バックグラウンド

【飛ばしていただいても構いません】

私は、馬、その所有者、および所有者のレースの色 (シルク) を扱うプログラムを構築しています。この質問は、 のビューとして機能するUserControlと呼ばれるに関するものです。SilksControlJockeySilks

シルクを表すために、次のクラスの列挙型を使用します。

public class JockeySilks
{
    public BodyPatterns BodyPattern { get; set; }
    public Colour BodyColour1 { get; set; }
    public Colour BodyColour2 { get; set; }

    public SleevePatterns SleevePattern { get; set; }
    public Colour SleeveColour1 { get; set; }
    public Colour SleeveColour2 { get; set; }

    public CapPatterns CapPattern { get; set; }
    public Colour CapColour1 { get; set; }
    public Colour CapColour2 { get; set; }
}

ご覧のとおり、ジョッキー シルクの要素ごとに異なるパターンと色があります。各要素の主要部分は [Item]Colour1 で、パターンは [Item]Colour2 で塗りつぶされます。

の基本的な構成は、SilksControlaViewBoxを含む aCanvasであり、これには多数の が含まれますPath。それぞれのパターンをPath子供の中に描いてみましたCanvas

これが写真です。この例では、CapPatternBodyPatternが に設定されPlain、 とArmPatternが に設定されていChevronsます。

問題

WPF データ バインディングに基づいてパターンを設定する最善の方法を見つけようとしています。ただし、1 つの問題があります。パターンごとに値と寸法Pathが異なります。「最善の方法」とは、シンプルで読みやすく、実装が簡単なものを意味します。Canvas.TopCanvas.Left

私が考えたアプローチ

  1. コード内のパスを切り替える -リソースからpthCapPattern = CapPatterns[SilksModel.CapPattern]どこCapPatternsにあるDictionary<CapPattern,Path>か、またはアクセスする ようなものかもしれません
    • しかし、バインディングではありません。いくつかのイベントやものを実装する必要があります
  2. SilksModel.[Item]Patternリソース/辞書からパスを生成/プルするコンバーターを使用して 、コントロール/パネルのコンテンツをバインドする
    • どのコントロール?
    • 新しいパス全体を生成する必要がある可能性があります
    • ややリソース集約型
  3. すべてPathの を XAML に配置し、それぞれの可視性を変更します
    • これはただ厄介で奇妙です
  4. 次元の違いを調整する方法を見つけてから、1 つのパスを作成し、そのPath.Dataプロパティにバインドします (おそらくリソースにいくつかStreamGeometryあり、コンバーターを使用して enum から に移動しますStreamGeometry)
    • それらに同じ寸法を与える方法、したがってCanvasオフセットを与える方法がわかりません。:(

したがって、解決策 4 が私の好みの解決策ですが、前述したように、それを行う方法がわかりません。また、Google のスキルでは、役立つものを思いつくことができません。それができない場合は、ソリューション 2 が次善の策ですが、キャンバスと同じ機能を提供し、子/コンテンツへのバインディングを提供するコンテナーを知りません。

編集1:

<Canvas x:Name="SPatterns" Height="173" Canvas.Left="6.8" Canvas.Top="107" Width="236.6">
    <Path x:Name="Chevrons" Fill="{Binding SilksModel.BodyColour2, Converter={StaticResource DBColourToColorConverter}, ElementName=root" Height="134.125" Canvas.Left="1.087" Stretch="Fill" Stroke="Black" Canvas.Top="21.667" Width="234.168" Data="M21.750001,94.749999 L34.000002,117.66218 30.625003,133.62501 17.000006,113.32909 0.5,126.75 3.2500048,108.125 z M212.418,93.416999 L230.918,106.79199 233.668,125.41701 217.168,111.99609 203.543,132.292 200.168,116.32917 z M32.25,48.374999 L44.250004,72.249999 40.625004,90.249999 28.000003,68.581336 7.750001,82.249999 11.665709,64.166339 z M201.918,47.041991 L222.50229,62.833335 226.418,80.916991 206.168,67.248336 193.543,88.916999 189.918,70.916991 z M41,1.8329993 L55.000002,28.166337 51.66667,45.832999 37.333336,23.499837 16.666001,37.417269 21.66571,19.418135 z M193.168,0.5 L212.50229,18.085143 217.502,36.084262 196.83467,22.166836 182.50133,44.499991 179.168,26.833333 z" />
    <!-- More SleevePatterns -->
</Canvas>
4

1 に答える 1

1

これは最もクリーンな解決策ではないかもしれませんが、このようなものはうまくいきますか (明らかに、ジオメトリの初期化をコンストラクターから移動します)?

提案されたDictionary<CapPattern,Path>オブジェクトを作成し、それにパス情報を入力することもできますが、 に を適用しTransformて、Geometryに対して希望する寸法/オフセットを与えることもできますCanvas

public partial class Horses : UserControl, INotifyPropertyChanged
{
    public enum CapPattern { ChevronPattern, SomeOtherPattern };
    public Dictionary<CapPattern, Geometry> Patterns { get; set; }

    private Geometry currentPath;
    public Geometry CurrentPath
    {
        get { return this.currentPath; }
        set 
        { 
            this.currentPath = value;
            NotifyPropertyChanged();
        }
    }

    public Horses()
    {
        Patterns = new Dictionary<CapPattern, Geometry>();          

        Patterns.Add(
            CapPattern.ChevronPattern,
            Geometry.Combine(
                Geometry.Parse("M21.750001,94.749999 L34.000002,117.66218 30.625003,133.62501 17.000006,113.32909 0.5,126.75 3.2500048,108.125 z M212.418,93.416999 L230.918,106.79199 233.668,125.41701 217.168,111.99609 203.543,132.292 200.168,116.32917 z M32.25,48.374999 L44.250004,72.249999 40.625004,90.249999 28.000003,68.581336 7.750001,82.249999 11.665709,64.166339 z M201.918,47.041991 L222.50229,62.833335 226.418,80.916991 206.168,67.248336 193.543,88.916999 189.918,70.916991 z M41,1.8329993 L55.000002,28.166337 51.66667,45.832999 37.333336,23.499837 16.666001,37.417269 21.66571,19.418135 z M193.168,0.5 L212.50229,18.085143 217.502,36.084262 196.83467,22.166836 182.50133,44.499991 179.168,26.833333 z"),
                Geometry.Empty, 
                GeometryCombineMode.Union, 
                new TranslateTransform(0, 0)));
        Patterns.Add(
            CapPattern.SomeOtherPattern, 
            Geometry.Combine(
                Geometry.Parse("M21.750001,94.749999 L34.000002,117.66218 30.625003,133.62501 17.000006,113.32909 0.5,126.75 3.2500048,108.125 z M212.418,93.416999 L230.918,106.79199 233.668,125.41701 217.168,111.99609 203.543,132.292 200.168,116.32917 z M32.25,48.374999 L44.250004,72.249999 40.625004,90.249999 28.000003,68.581336 7.750001,82.249999 11.665709,64.166339 z M201.918,47.041991 L222.50229,62.833335 226.418,80.916991 206.168,67.248336 193.543,88.916999 189.918,70.916991 z M41,1.8329993 L55.000002,28.166337 51.66667,45.832999 37.333336,23.499837 16.666001,37.417269 21.66571,19.418135 z M193.168,0.5 L212.50229,18.085143 217.502,36.084262 196.83467,22.166836 182.50133,44.499991 179.168,26.833333 z"), 
                Geometry.Empty, 
                GeometryCombineMode.Union, 
                new TranslateTransform(20, 30)));           

        InitializeComponent();
    }

    // INotifyPropertyChanged implementaton.

}

私のモックアップでComboBoxは、 プロパティ を設定する辞書から を取り込みましたCurrentPath。これは の にバインドされてPathCanvasます。

<Grid>
    <StackPanel>
        <ComboBox ItemsSource="{Binding Path=Patterns}"
                  SelectedValue="{Binding Path=CurrentPath}"
                  SelectedValuePath="Value"
                  DisplayMemberPath="Key"/>
        <Canvas>
            <Path Data="{Binding Path=CurrentPath}" Stroke="Black" StrokeThickness="1" />
        </Canvas>
    </StackPanel>
</Grid>

Fillおよびその他のプロパティのバインディングを保持します。

別のアプローチは、必要な、、またはパターンを配置するために必要なその他の情報と一緒に、情報Classを保持する小さなものを作成することです。次に、上記と同様の方法でこれらのオブジェクトのリストを にバインドし、必要なすべてのプロパティを現在選択されているオブジェクトのプロパティにバインドできます。PathTopLeftTransformComboBoxCanvasPath

編集:

ResourceDictionary次の行に沿って変換を構成することもできます。

<Path x:Name="Chevrons" Fill="{Binding SilksModel.BodyColour2, Converter={StaticResource DBColourToColorConverter}, ElementName=root" Data="M21.750001,94.749999 L34.000002,117.66218 30.625003,133.62501 17.000006,113.32909 0.5,126.75 3.2500048,108.125 z M212.418,93.416999 L230.918,106.79199 233.668,125.41701 217.168,111.99609 203.543,132.292 200.168,116.32917 z M32.25,48.374999 L44.250004,72.249999 40.625004,90.249999 28.000003,68.581336 7.750001,82.249999 11.665709,64.166339 z M201.918,47.041991 L222.50229,62.833335 226.418,80.916991 206.168,67.248336 193.543,88.916999 189.918,70.916991 z M41,1.8329993 L55.000002,28.166337 51.66667,45.832999 37.333336,23.499837 16.666001,37.417269 21.66571,19.418135 z M193.168,0.5 L212.50229,18.085143 217.502,36.084262 196.83467,22.166836 182.50133,44.499991 179.168,26.833333 z" Stroke="Black" StrokeThickness="1">
    <Path.RenderTransform>
        <TranslateTransform X="20" Y="120"/>
    </Path.RenderTransform>
</Path>
于 2013-08-03T22:23:00.870 に答える