我应该在MVVM或ViewModel中的用户控件代码中创建图形对象吗?

时间:2016-04-06 08:58:40

标签: c# wpf mvvm

我正在编写一个我在WPF中编写的图形/图表代码库,以与MVVM设计模式保持一致。我目前有一个用户控件,里面有一个画布。我在后面的代码中计算需要绘制的元素的位置/大小,因此其中有很多相当的代码。我相信计算图形属性的大部分逻辑应该移出后面的代码并进入ViewModel,但是我有点不确定是否应该移动实际创建形状的代码,因为它实际上是关于View的。

以下是用于在饼图中绘制每个段的标签的代码中的示例方法:

private void drawSegmentLabel(CatagoricalDataPoint dataPoint, double totalAngle, double segmentAngle)
{
    //Calculate the X and Y coordinates of the label
    double x = centerPoint.X + (radius + 20) * Math.Cos(totalAngle + segmentAngle / 2);
    double y = centerPoint.Y + (radius + 20) * Math.Sin(totalAngle + segmentAngle / 2);

    //Create the Textblock that represents the percentage of the segment
    TextBlock segmentLabel = new TextBlock();
    segmentLabel.Text = Math.Round(((double)dataPoint.value / data.TotalValue) * 100).ToString() + "%";
    segmentLabel.FontFamily = new FontFamily("Calibri Light");
    segmentLabel.FontWeight = FontWeights.Bold;
    segmentLabel.FontSize = 16;
    segmentLabel.Width = 60;
    segmentLabel.Tag = dataPoint;
    segmentLabel.TextAlignment = TextAlignment.Center;
    segmentLabel.Foreground = new SolidColorBrush(Colors.Black);

    //If the label is on the right side of the center then align it to the left and vica versa
    if (x >= centerPoint.X)
    {
        Canvas.SetLeft(segmentLabel, x);
        segmentLabel.TextAlignment = TextAlignment.Left;
    }
    else
    {
        Canvas.SetLeft(segmentLabel, x - segmentLabel.Width);
        segmentLabel.TextAlignment = TextAlignment.Right;
    }

    Canvas.SetTop(segmentLabel, y - 10);
    GraphCanvas.Children.Add(segmentLabel);
}

正如您所看到的,有一些线条计算位置,一些线条创建视觉元素。这些行应该在单独的文件中吗?

我绘制的大多数形状都在system.windows.media命名空间中。而不是控件,如上例中的文本块。

2 个答案:

答案 0 :(得分:2)

我不知道你的dataPoint到底是什么,但这有点像View中不应该出现的那样。不应将dataPoint实例存储在Tag实例的TextBlock属性中,而应考虑将TextBlock绑定到dataPoint中代表ViewModel的内容。 1}}。 Text属性值的计算应该在自定义值转换器中完成。

其他任何东西看起来应该保留在View的代码隐藏中,因为它确实是与视图相关的代码,而不是与数据相关的东西。

答案 1 :(得分:1)

要在代码隐藏中保持清除(移动某些UI逻辑),您可以创建新的cs文件。它还不错,因为它给出了许可,所以它更可取。

这只是View的交易,而不是ViewModelViewModel的主要目标是易懂,并且是View的数据表示,而不是Views

例如,您有PersonViewPersonViewModel。所以PersonViewModel中有UI逻辑。然后您的UI设计师更改了您的View,然后您的PersonViewModel将包含不必要的图形代码,或者此图形代码不适用于新的PersonView,但可以使用之前的版本。因此,我们可以得出结论:ViewViewModel之间存在联系。这违反了MVVM。为了避免这种情况,只需保持逻辑(ViewModel)和UI(View)之间的间隙。

动画,样式,模板等动作是Views的交易,完全是View.xaml.csView.xaml的交易。