4

背景

[随意跳过此]

我正在构建一个程序来处理马、它们的主人和主人的赛马颜色(丝绸)。这个问题是关于一个UserControl,称为SilksControl作为视图的JockeySilks

为了表示丝绸,我使用以下枚举类:

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 填充。

the 的基本组成SilksControlViewBox包含 a 的 a,Canvas而 a 又包含多个Paths。我把每个图案都画Path成了一个孩子的 s Canvas

这是一张图片。在本例中,CapPatternBodyPattern设置为Plain, 和ArmPattern设置为Chevrons

问题

我试图找出基于 WPF 数据绑定设置模式的最佳方法。但是,有一个问题:每种模式Path都有不同Canvas.TopCanvas.Left值和维度。“最佳方式”是指简单、易读且易于实现的方式。

我考虑过的方法

  1. 在代码中切换路径 - 可能类似于pthCapPattern = CapPatterns[SilksModel.CapPattern]where CapPatternsis aDictionary<CapPattern,Path>或可能从资源中访问它
    • 但不是绑定,我必须实现一些事件和东西
  2. SilksModel.[Item]Pattern使用从资源/字典生成/拉出路径的转换器将 某些控件/面板的内容绑定到
    • 哪个控制?
    • 可能必须生成全新的路径
    • 有点资源密集型
  3. 拥有PathXAML 中的所有 s 并更改每个 s 的可见性
    • 这只是尴尬和奇怪
  4. 找出一种调和维度差异的方法,然后创建 1 个路径并绑定到其Path.Data属性(可能StreamGeometry在资源中有一些,使用转换器从 enum 转到StreamGeometry
    • 我不知道如何给它们相同的尺寸和Canvas偏移量。:(

所以解决方案 4 是我的首选解决方案,但正如我所提到的,我不知道我该怎么做,而且我的谷歌搜索技能也想不出任何有用的东西。如果做不到这一点,解决方案 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>对象并使用您的路径信息填充它,但也可以将 aTransform应用于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文件,其中包含您的Path信息,以及所需TopLeftTransform或定位模式所需的任何其他信息。然后,您可以以与上述类似的方式将这些对象的列表绑定到 a ComboBox,并将所有必需的属性绑定到当前选定对象的属性上CanvasPath

编辑:

您还可以按照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 回答