首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将数据从视图绑定到ItemsPanelTemplate

将数据从视图绑定到ItemsPanelTemplate
EN

Stack Overflow用户
提问于 2014-04-08 22:30:15
回答 2查看 533关注 0票数 1

我一直在开发我的第一个MVVM应用程序,在该应用程序中,我想绘制一个包含节点和边的图表。目前,我正在执行视图后面的代码中的所有绘图逻辑,迭代节点,相应地创建形状并将它们添加到画布中。

因为我不想跟踪形状,只想根据给定的数据(即节点)绘制形状,所以我决定创建一个ObservableCollectionNodesEdges,并将ItemsControl绑定到这些数据,以便自动绘制形状。

目前,我的重点是绘制节点,并提出了以下XAML代码:

代码语言:javascript
复制
<ItemsControl x:Name="ItemsControlCanvas" ItemsSource="{Binding Path=Nodes}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas>
                <Canvas.LayoutTransform>
                    <ScaleTransform ScaleX="{Binding ?}" ScaleY="{Binding ?}"/>
                </Canvas.LayoutTransform>
            </Canvas>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Fill="Blue" Width="4" Height="4" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Canvas.Top" Value="{Binding Path=Position.Y}" />
            <Setter Property="Canvas.Left" Value="{Binding Path=Position.X}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

在我看来,我有两个属性ScaleXScaleY,这两个属性是当用户在画布上滚动时设置的。在我的早期版本代码中,我将使用这些属性创建一个ScaleTransform,并使用LayoutTransform将其应用到命名的画布中。

代码语言:javascript
复制
public partial class GraphOverview : Page
{
    public double ScaleX { get; set; }
    public double ScaleY { get; set; }

这个版本的问题是,我无法让它在我的新XAML代码中工作。我希望将ScaleXItemsPanelTemplate中的ScaleTransform属性绑定到我的视图中的属性。只是,由于某些原因,普通的ElementName绑定无法工作。更清楚的是,我认为画布可能不知道视图,因为它是一个模板。此外,我不能从后面的代码调用画布,即使它有一个名称。

我尝试过几种解决方案,在RelativeResources等方面摸索,但我想我不明白为什么ItemsPanelTemplate与XAML代码中的其他所有东西都如此断开。提前感谢!

更新

也许我应该澄清,通过将ScaleXScaleY属性移动到ViewModel,并绑定到这些属性,可以很容易地解决这一问题。但在我看来,这种特定于视图的属性不应该驻留在ViewModel中。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-09 10:24:16

当您说视图特定信息不应该在视图模型中时,您是正确的。但是在您的情况下,这些位置成为模型的一部分,因为这些位置只不过是您的视图应该基于的数据。在这种情况下,您可以将它们视为模型的一部分,而不是视图。编写一个单独的模型类,并在ViewModel类的可观察集合中使用它。我希望这能消除你的疑虑。

代码语言:javascript
复制
public class Node
{
    public double ScaleX { get; set; }
    public double ScaleY { get; set; }
}

编辑

回答你的问题。-

但是Scale属性指定画布的行为方式,那么View是否已经成为了这方面的“模型”呢?在我看来,创建一个新的模型来设置单个画布的比例属性似乎是多余的吗?视图应该仅仅关注绘图数据,而且由于属性作为这些绘图的修改,它们属于视图,不是吗?

您希望根据所提供的数据绘制图表。Node类将为您提供数据。它存储数据,而不是存储画布应该呈现的逻辑,XAML代码使用这些数据,并具有在视图中显示数据的逻辑。

,那么视图是否已经成为这方面的“模型”?

您尝试过的实现将模型包含在视图中,其思想是将模型与视图分开。最初创建一个类来容纳2个双值看起来可能是多余的。但是,如果你把它们从视野中抽离,就会有一些好处。

  • 在视图模型中,您可以为这个Node类( model )创建一个可观察的集合。如果视图中有ScaleX和ScaleY,则无法从视图模型访问它。
  • 将来,您可能希望将ScaleX和ScaleY更改为不同的标度,例如Logarmic /不同的单元。在这种情况下,您必须更改ViewModel中的逻辑才能做到这一点,而且永远不必担心更改视图。但是,如果视图中有这个可观察的集合,则必须更改对数据/模型进行更改的视图。
  • 最后,您可以为ViewModel中的任何东西编写单元测试,而不是为视图编写单元测试。

通常,ScaleX和ScaleY将是视图的一部分,但在您的示例中,它们会更改并存储数据。因此,您需要将这个ScaleX和ScaleY抽象到一个不同的层中,以保留MVVM的概念。

票数 1
EN

Stack Overflow用户

发布于 2014-04-09 00:28:03

我不确定您是否设置了视图的DataContext,这有助于在后面显示更多的代码

代码语言:javascript
复制
internal ViewModel viewModel { get; set; }

public View()
{
      DataContext = (viewModel = new ViewModel());
}

您是否将ObservableCollection绑定到节点的ItemSource?我不熟悉绘画,但是当我和孩子们在一起的时候,我从来没有取得过成果。

但是我只开发了大约4个使用MVVM的项目。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22949449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档