【问题标题】:Render Bitmap in UWP with MVVM使用 MVVM 在 UWP 中渲染位图
【发布时间】:2018-03-21 14:12:35
【问题描述】:

在我后面的代码中,我使用RenderTargetBitmap 从我的网格渲染位图。

var renderBitmap = new RenderTargetBitmap();
await renderBitmap.RenderAsync(UIElement);

我想使用 MVVM 模式,但现在 RenderTargetBitmap 类不再工作了。

现在我正在尝试使用 WinRT XAML 工具包 - 组合

var gridBitmap = await WriteableBitmapRenderExtensions.Render(Grid);

然后我得到这个错误:消息"Unable to expand length of this stream beyond its capacity."字符串

还有其他方法可以在 MVVM 中呈现它吗?也许是SharpDX?还是我做错了什么?

【问题讨论】:

  • 如果您认为位图数据是否是“视图”,这实际上是一个意识形态/哲学问题。理想情况下,我们会更多地了解您的应用程序的性质。
  • 另外,请注意 MVVM 并不意味着您永远不应该使用 Code-behind。使用代码隐藏逻辑没有任何问题 - 只是代码隐藏逻辑应该只关注“视图”而不是其他任何东西,例如业务规则或数据库查询 - 所以在代码中对位图执行操作-behind 可能完全适合您的应用程序。

标签: xaml uwp toolkit rendertargetbitmap


【解决方案1】:

这里的问题是,将 UI 元素渲染为位图实际上不是视图模型的任务,因为它非常特定于视图。在这种情况下,我认为将此代码放在页面代码后面并使其可以从视图模型触发此方法没有什么害处。

根据您使用的 MVVM 框架,您可以通过不同的方式触发该功能。首先是用这个方法让页面实现一个像IRenderGrid这样的接口,然后在视图模型中添加一个新方法,它将IRenderGrid作为参数并存储实例供以后使用,然后在@987654323中页面的@调用此视图模型方法。

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

当然问题是,如果您的视图模型驻留在不同的程序集中,您将无法访问那里的Bitmap,因此您必须将其包装在一些自定义类型中。

触发页面方法的替代方法是使用许多 MVVM 框架提供的信使。在这种情况下,您将订阅视图中的触发消息,并通过执行渲染对此类消息做出反应,然后使用另一条消息或通过公共方法将结果传递给视图模型。

【讨论】:

  • 谢谢。我已经考虑过了。我不使用我手工编写模式的框架。我今天会试试你的代码!
猜你喜欢
  • 2013-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-15
  • 2016-07-30
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多