Friends! There is a main window, it contains a frame with which I switch between pages. I have a page that has a canvas. Canvas in the background stream receives data in the form of images in a mosaic view.
foreach (var item in CoreData.fillWallArray.GetConsumingEnumerable())
{
if (File.Exists(item.PathFile))
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
Image image = new Image();
image.Source = BitmapImageFromFile(item.PathFile);
image.Width = (int)Math.Truncate((CoreData.settings.CellWidth * 30) / 2.54);
image.Height = (int)Math.Truncate((CoreData.settings.CellHeight * 30) / 2.54);
Canvas.SetLeft(image, item.Column * (int)Math.Truncate((CoreData.settings.CellWidth * 30) / 2.54));
Canvas.SetTop(image, item.Row * (int)Math.Truncate((CoreData.settings.CellHeight * 30) / 2.54));
can.Children.Add(image);
}));
Thread.Sleep(100);
}
}
My task is to bring this canvas to the second screen. To do this, I create a second window and, as a context, pass the canvas that I need.
var _BroadcastWindow = new BroadcastWindow();
_BroadcastWindow.DataContext = this.can;
_BroadcastWindow.Show();
And in the second window, I link the data.
<Grid>
<Grid.Background>
<VisualBrush Visual="{Binding}"/>
</Grid.Background>
</Grid>
Everything works fine, data from the canvas synchronously displayed in the second window. But as soon as I switch to another page, the Visualbrush is no longer updated. As soon as I switch back to the page with the canvas I see in the second window, it is updated. What could be the problem? I also tried to call Measure, Arrange, UpdateLayout when adding data to the canvas in the background thread, but this did not produce results.
I assume when you say "go to another page" you mean something along the lines of:
Every time you do this, your app loads a new
Pagefrom a given source. If the current page happens to be thePagethat has yourCanvason it, navigation will create a newCanvasinstance. If not, and there is no JournalEntry.KeepAlive="true" set for thePagewith yourCanvas, then contents of theFramewill just get recreated from theSourcefile every time it is displayed, and a newCanvaswill be created with it. Something will get disconnected or prematurely destroyed at some point. Even withKeepAliveset toTrue, you'll probably just end up with multiple instances ofCanvasloaded in memory. Which one do you want to bind to...?Some alternative approaches off the top of my head:
Cache the
Imageitself in your View Model and bind both yourCanvason thePageand theVisualBrushto that.Cache the whole
Canvasin your View Model, then switch its contents as needed.The second approach required only minimal changes to your code, so I could throw in a working example (although I don't know if it's the most optimal):
In
Page1.xaml(the page that displays the Canvas):In
BroadcastWindow.xaml:Example singleton View Model to hold the canvas:
Switching between images in the
Clickevent of aButtonoutside of Frame: