The problem here is that rendering a UI element into a bitmap is really not a task for view model, as it is very View-specific. In this case then I would see no harm in putting this code in the page's code behind and making it possible to trigger this method from the view-model.
Depending on the MVVM framework you are using, you could trigger the function in different ways. First would be to make the page implement an interface like IRenderGrid
with this one method, then add a new method to the view-model that will take IRenderGrid
as parameter and store the instance for later use, and then in OnNavigatedTo
of the page call this view model method.
interface IRenderGrid
{
Bitmap RenderGrid();
}
class MainViewModel
{
...
private IRenderGrid _renderGrid;
public void RegisterRenderGrid( IRenderGrid renderGrid )
{
_renderGrid = renderGrid;
}
}
class MainPage : Page, IRenderGrid
{
...
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var viewModel = DataContext as MainViewModel;//get the view model
viewModel.RegisterRenderGrid( this );
}
public Bitmap RenderGrid()
{
var renderBitmap = new RenderTargetBitmap();
await renderBitmap.RenderAsync(Grid);
}
}
Of course the problem is that if your view models reside in a different assembly, you will not have access to Bitmap
there, so you will have to wrap it in some custom type.
Alternative approach to triggering the page's method would be to use a messenger, which many MVVM frameworks offer. In such case you would subscribe to a trigger message in the view and react to such message by executing the rendering and then pass the result to the view model either with another message or through a public method.