1

I am re writing a graphing / diagram code library I wrote in WPF to be consistent with the MVVM design pattern. I currently have a user control which has a canvas inside it. I calculate the positions / size of the elements which need to be drawn to it in the code behind so there is quite alot of code in it. I believe most of the logic that calculates the properties of the graph should be moved out of the code behind and into the ViewModel but i am a bit unsure if I should move the code that actually creates the shapes since it is actually regarding the View.

Here is an example method in the code behind used to draw the labels of each segment in a pie chart:

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);
}

As you can see there are some lines calculating positions and some lines creating the visual elements. Should these lines be in separate files?

Most of the shapes I am drawing are in the system.windows.media namespace. rather then controls such as the textblock in the example above.

Timmoth
  • 480
  • 2
  • 18

2 Answers2

2

I don't know what exactly your dataPoint is, but this smells like it shouldn't be there in the View. Instead of storing the dataPoint instance in the Tag property of the TextBlock instance, you should consider binding the TextBlock to something representing this dataPoint in the ViewModel. The calculation of the Text property value should probably be done inside a custom value converter.

Anything else looks like it should remain in the code-behind of the View, as it is indeed view-related code, not data-related stuff.

Kim Homann
  • 3,042
  • 1
  • 17
  • 20
1

To keep clearance(moving some UI logic) in code-behind, you can create new cs files. It is not bad, it is preferable as it gives clearance.

It is a deal just of View, not the ViewModel. The main goal of ViewModel is to be teastable and to be data representation of View and not be coupled with Views.

For example, you have PersonView and PersonViewModel. So there is UI logic in PersonViewModel. Then your UI designer has changed your View, then your PersonViewModel will have unnecessary graphical code or this graphical code won't work with new PersonView, but works with previous. So we can conclude that there is a tie between View and ViewModel. It is violation of MVVM. To avoid such situations just keep clearance between logic(ViewModel) and UI(View).

So actions like Animation, Styling, Templating are deals of Views, to be exact a deal of View.xaml.cs or View.xaml.

StepUp
  • 36,391
  • 15
  • 88
  • 148
  • @ASh I mean that OP code should be placed in `View`, not in `ViewModel`. – StepUp Apr 06 '16 at 09:17
  • yeah, but question of OP is `Should I create graphical objects in a user controls code behind in MVVM or in the ViewModel?`. So I try to answer about where UI logic should be placed. – StepUp Apr 06 '16 at 09:21