【问题标题】:binding different types of objects to canvas将不同类型的对象绑定到画布
【发布时间】:2013-11-11 14:03:26
【问题描述】:

我试图在画布上“扔”几个对象。 我有 5 种类型的对象,具有多个属性(如文本、位置、位图等)

每种类型都应该以不同的方式呈现(一种类型将呈现为文本块,一种类型将呈现为 bitmapImage 等)

我有 5 个 observableCollections 包含所有相同类型的对象。

我可以将其中一个(例如表示文本的那个)绑定到画布,并使用带有文本块的数据模板将每个属性绑定到正确的参数(例如可见性和位置)。

现在我的第二种类型应该绑定到位图。

我该怎么做?如何将 5 种不同类型绑定到画布并将每种类型转换为正确的元素?

一种可能的方法是将所有集合聚合为一个集合...但随后它会尝试将所有内容转换为第一种类型...

【问题讨论】:

    标签: wpf


    【解决方案1】:

    有一个great answer 与某种相关的问题,我们可以扩展它以解决您的问题。

    假设我们有两种可以拖放到 Canvas 的类型:

    public class TextClass
    {
       public string Text { get; set; }
    }
    
    public class RectangleClass
    {
       public Brush FillBrush { get; set; }
    }
    

    为了方便使用集合绑定到我们可以使用我提到的答案中的代码,但将ItemTemplate更改为我们自定义的DataTemplateSelector

     <ItemsControl Name="icMain">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Canvas.Left" Value="{Binding Left}" />
                    <Setter Property="Canvas.Top" Value="{Binding Top}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplateSelector>
                <TestWPF:CustomTemplateSelector>
                    <TestWPF:CustomTemplateSelector.TextTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Text}" />
                        </DataTemplate>
                    </TestWPF:CustomTemplateSelector.TextTemplate>
                    <TestWPF:CustomTemplateSelector.RectangleTemplate>
                        <DataTemplate>
                            <Rectangle Height="25" Width="25" Fill="{Binding FillBrush}" />
                        </DataTemplate>
                    </TestWPF:CustomTemplateSelector.RectangleTemplate>
                </TestWPF:CustomTemplateSelector>
            </ItemsControl.ItemTemplateSelector>               
        </ItemsControl>
    

    这就是我使用的模板选择器:

    public class CustomTemplateSelector: DataTemplateSelector
    {
       public DataTemplate TextTemplate { get; set; }
       public DataTemplate RectangleTemplate { get; set; }
    
       public override DataTemplate SelectTemplate(object item, DependencyObject container)
       {
          if (item is TextClass)
             return TextTemplate;
          else if (item is RectangleClass)
             return RectangleTemplate;
          else return base.SelectTemplate(item, container);
       }
    }
    

    好吧,剩下的就是绑定我们的集合了。我在后面的代码中使用了简单的List 来进行测试:

    List<object> aggregation = new List<object>()
          {
               new TextClass() { Text = "Some test text" },
               new RectangleClass() { FillBrush = new SolidColorBrush(Colors.Tomato)}
          };
    
    icMain.ItemsSource = aggregation;
    

    这段代码显示了一些测试文本和美味的番茄矩形。这些示例对象没有任何定位逻辑,但我想你已经有了。

    【讨论】:

    • 谢谢,明天试试,告诉你进展如何。
    • 很高兴它有帮助,@Dani!
    • @icebat 我用什么代替 TestWPF: ?我是 wpf 的新手,我不知道那是命名空间、类、变量还是什么。谢谢
    • @icebat 我最终不得不使用 local: 而不是 TestWPF: 然后必须关闭 VS 并以管理员身份打开它才能识别。
    猜你喜欢
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2022-11-18
    相关资源
    最近更新 更多