Question

I'm actually trying to add in a asynchronous way some UIElement to my Canvas define in my MainPage.

As I understand the basic way to add UIElement to a Canvas is to add it on his UIElementCollection, for example with a Line I should do like that:

        Line line = new Line();

        // Line attributes
        line.Stroke = new SolidColorBrush(Colors.Purple);
        line.StrokeThickness = 15;
        Point point1 = new Point();
        point1.X = 0;
        point1.Y = 0;
        Point point2 = new Point();
        point2.X = 480;
        point2.Y = 720;
        line.X1 = point1.X;
        line.Y1 = point1.Y;
        line.X2 = point2.X;
        line.Y2 = point2.Y;
        // Line attributes

        MyCanvas.Children.Add(line);

Let's imagine that I have a Class call Graphics that needs to access this Canvas in order to draw on it.

 public class Graphics
 {
     public void drawLine()
     {
            //Using Dispatcher in order to access the main UI thread
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
               Line line = new Line();

               // Line attributes

               /**
                *  Here I want to access the Canvas of the MainPage
                *  I have no Idea what to put here !!!
                *
                **/

            });
      }
  }

In the place "I have no Idea what to put here !!!" I tried to access directly to the MainPage Canvas --> FAIL

I tried to declare a public static UIElementCollection in the MainPage in order ta add my UIElement then pass it to the Canvas but not possible because UIElementCollection has no constructor --> FAIL

But those ideas seems to be dirty coding and not really elegant. So through my research I see that MVVM should do the magic. But all the tutorial I found were doing the data-biding through the xaml file which can't be use in my case.

So I have 2 questions:

First: How is use the UIElementCollection of the Canvas? (is there a hidden method called who draws it, like Paint or Repaint in JAVA?)

Second: If I want to follow the MVVM pattern can I consider the MainPage as my View, the Graphics class as my ViewModel and the UIElement as my Model?

Was it helpful?

Solution

This is a really basic example but should get you going in the correct direction.

Graphics.cs

 public class Graphics
{
    public ObservableCollection<UIElement> UIElements { get; set; }
    int poisiton = 0;
    private Timer backgroundTimer;
    public Graphics()
    {
        this.UIElements = new ObservableCollection<UIElement>();
        this.backgroundTimer = new Timer(new TimerCallback((timer) => {
            Deployment.Current.Dispatcher.BeginInvoke(() => this.GenerateLine());
        }), null, 2000, 3000);
    }

    private void GenerateLine()
    {
        Line line = new Line();

        // Line attributes
        line.Stroke = new SolidColorBrush(Colors.Purple);
        line.StrokeThickness = 15;
        Point point1 = new Point();
        point1.X = this.poisiton;
        point1.Y = this.poisiton;
        Point point2 = new Point();
        point2.X = this.poisiton;
        point2.Y = this.poisiton + 30;
        line.X1 = point1.X;
        line.Y1 = point1.Y;
        line.X2 = point2.X;
        line.Y2 = point2.Y;
        // Line attributes

        this.poisiton += 10;
        UIElements.Add(line);
    }
}

MainPage.xaml.cs

 public MainPage()
 {
      InitializeComponent();

      this.Loaded += MainPage_Loaded;
      // Sample code to localize the ApplicationBar
      //BuildLocalizedApplicationBar();
 }

  void MainPage_Loaded(object sender, RoutedEventArgs e)
  {
      var graphics = new Graphics();
      this.ContentPanel.DataContext = graphics;
  }

MainPage.xaml

  <Canvas x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      <ItemsControl ItemsSource="{Binding UIElements}">

      </ItemsControl>
  </Canvas>

I hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top