Render Bitmap in UWP with MVVM - xaml

In my code behind I used to render the bitmap from my grid with RenderTargetBitmap.
var renderBitmap = new RenderTargetBitmap();
await renderBitmap.RenderAsync(UIElement);
I want to use the MVVM pattern but now the RenderTargetBitmap class does not work anymore.
Now I'm trying to use the WinRT XAML Toolkit - Composition
var gridBitmap = await WriteableBitmapRenderExtensions.Render(Grid);
but then I get this error: Message "Unable to expand length of this stream beyond its capacity." string
Is there a other way to render this in MVVM? Maybe with SharpDX? Or Iam doing anything wrong?

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.

Related

Access to container of Simple Injector MVC views

In a Sitecore project I've integrated Simple Injector using this article
It uses sitecore pipelines and then uses a method in App_start
namespace BBC.App_Start
{
public class SimpleInjector : IPackage
{
public void RegisterServices(Container container)
{
GetContainer.RegisterServices(container);
container.Register(() => new SitecoreContext(), Lifestyle.Scoped);
container.Register(() => new Container(), Lifestyle.Singleton);
}
}
}
Simply I can inject container into controller constructor but can't have container in View files.
I tried to declare a static property in App-start and save container to it. but still I'm getting no registration type in Views
What is the best way to have container object in views?
As Stephen suggests in his comment, the literal answer to your question is "you shouldn't do that - because it's not really the way MVC and DI are supposed to work". The more detailed answer goes something like this:
The job of your view is to present data that it has been passed via the Model. Views should not really contain logic. Very simple stuff like "if flag is false, hide this block of mark-up" is ok, but the more complex code to work out what the value of the flag is shouldn't be in the view.
MVC tries to make our website code better by encouraging you to separate presentation (the View) from data (the Model) and logic (the Controller). This should make our code easier to work with - So if you have processing that needs doing, then it should really be happening when your controller method runs.
If your view requires some special data, best practice suggests it should work it out in the controller method and pass it to the view in the model. The code might look more like this:
public class MyModel
{
public string SpecialData { get; set; }
}
public class MyController : Controller
{
public ActionResult DoSomething()
{
// do whatever processing is needed
var somethingCalculate = resultFromYourOtherObject();
// do other stuff
var model = new MyModel() { SpecialData = somethingCalculated };
return View(model);
}
}
And then the View just needs to accept the MyModel class as its model, and render the SpecialData property - no logic required.
I think also it's considered a bad idea to have calls to fetch objects from your DI container spread about your codebase. For MVC apps, generally your DI container gets wired in to the process of creating a controller for a request when the app starts up. Rather than passing about a DI Container into your controllers, the DI framework extends the Controller-creation process, and the container isn't exposed outside of this. When the MVC runtime needs to create a controller, the controller-creation logic uses the DI framework to fetch objects for all the controller's dependencies.
Without more detail about what you actually want to achieve, it's difficult to say what the "right" approach to creating your object(s) here is, but the two most common patterns are probably:
1) Constructor injection: Your controller has a parameter which accepts the object required. The DI container creates this object for you at the point where it creates the controller, so your controller gets all its dependencies when it is created. Good for: scenarios where you know how to create the object at the beginning of the request.
public interface IMySpecialObject
{
string DoSomething();
}
public class MyController : Controller
{
private IMySpecialObject _specialObject;
public MyController(IMySpecialObject specialObject)
{
_specialObject = specialObject;
}
public ActionResult RenderAView()
{
// do some stuff
var data = _specialObject.DoSomething();
return View(data);
}
}
As long as IMySpecialObject and a concrete implementation for it are registered with your DI container when your app starts up, all is well.
2) Factory classes: Sometimes, however, the object in question might be optional, or it might require data that's not available at controller-creation time to create it. In that case, your DI framework could pass in a Factory object to your controller, and this is used to do the construction of the special object later.
public interface ISpecialFactory
{
ISpecialObject CreateSpecialObject(object data);
}
public class MyController : Controller
{
private IMySpecialFactory _specialFactory;
public MyController(IMySpecialFactory specialFactory)
{
_specialFactory = specialFactory;
}
public ActionResult RenderAView()
{
// do some stuff
if( requireSpecialObject )
{
var data = getSomeData();
var specialObject = _specialFactory.CreateSpecialObject(data);
var data = _specialObject.DoSomething();
return View(data);
}
return View("someOtherView");
}
}
But a good book on using DI may suggest other approaches that fit your specific problem better.

Xamarin Prism MasterDetailPage.IsPresented from child ViewModel

Does anyone have a clue on how to control IsPresented property from a child view model?
I'm implementing a custom NavBar where I want to simulate the Hamburger icon behavior so my child page on load has
NavigationPage.SetHasNavigationBar(this, false);
which hides the navigation par.
Inside Xaml file I have a button which I want to bind to a PropertyCommand of child viewmodel and show Master page, basically somehow to call Master's IsPresented.
Thanks.
There are a couple of ways to go about it.
The way I would do it would be to use MVVM and use an interface to access the 'presenting the Master page' functionality where its needed.
public interface ICustomMasterDetail
{
void SetMasterPresented(bool isPresented);
}
Now extend on the MasterDetailPage and also implement the above interface
public class CustomMasterDetail : MasterDetailPage, IRootMasterDetail
{
public CustomMasterDetail() : base()
{
//constructor code
}
public void SetMasterPresented(bool isPresented)
{
IsPresented = isPresented;
}
}
Using using an IoC container to register and resolve the interface will let you use its functionality from where ever you want.
The other solution would be to just use a static variable to store the instance of your MasterDetailPage and access that directly to change the IsPresented property

Vertex renderered as JComponent

I am currently trying to migrate a JGraph 5 application to JGraphX. I have vertex renderers implemented as nested JComponent with complex layout.
Using the mxStylesheet is the only I found so far to customize the vertext rendering. Is there any renderer concept in JGraphX ? Is it possible to implement the renderers as JComponents?
I found the answer in the CustomCanvas.java JGraphX sample.
This sample works fine for non-composite components (JLabel...) but fails for composite components. The paintComponent() method is called for the parent but not for the children. It seems to be related to the fact that the CellRendererPane as no parent in this sample. Adding to the CellRendererPaneto the graphComponent solved the problem (For me the canvas was the natural parent but it doesn't seem to be a container).
So, the answer to my original question is: no, JGraphX doesn't provide support for renderers but it seems that you can add such support yourself by subclassing both mxGraph, mxGraphComponent and mxInteractiveCanvas.
Finally, this sample can easily be extended to implement the "renderer" pattern in a more usual way. I did not introduce a renderer factory to keep the snippet short but that would probably make sense.
public class SwingCanvas<USER_OBJECT> extends mxInteractiveCanvas {
private final CellRendererPane rendererPane = new CellRendererPane();
protected mxGraphComponent graphComponent;
public SwingCanvas(SwingMxGraphComponent<USER_OBJECT> graphComponent) {
this.graphComponent = graphComponent;
graphComponent.add(rendererPane);
}
public void drawVertex(mxCellState state, String label) {
SwingMxGraph<USER_OBJECT> graph = graphComponent.getGraph();
VertexRenderer<USER_OBJECT> vertexRenderer = graph.getVertexRenderer();
USER_OBJECT userValue = (USER_OBJECT)((mxCell)state.getCell()).getValue();
JComponent rendererComponent = vertexRenderer.getRendererComponent(graphComponent.getGraph(), userValue);
rendererPane.paintComponent(g, rendererComponent, graphComponent,
(int) state.getX() + translate.x,
(int) state.getY() + translate.y,
(int) state.getWidth(), (int) state.getHeight(), true);
}
}
public interface VertexRenderer<USER_OBJECT> {
/* Provide graph instance just in case...*/
JComponent getRendererComponent(mxGraph graph, USER_OBJECT userObject);
}
public class SwingMxGraph<USER_OBJECT> extends mxGraph {
private VertexRenderer<USER_OBJECT> vertexRenderer;
/* Add the same method override as in sample
...
... */
public VertexRenderer<USER_OBJECT> getVertextRenderer() {
return vertexRenderer;
}
}

how to translate passing a listener in a java example to .net in monodroid

Using a monodroid java bindings project of Android Universal Image Library, how would I translate this from java to .net? Can I pass it in a lambda for the loading listener?
The Java code example
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
hideSpinner();
//do I set the image view to the view we get back here?
}
});
.NET ?
ImageLoader.Instance.LoadImage(imageUri, ... can I put a lambda in here or do I have to
C# does not support anonymous classes with Interface implementations, such can only implement public read-only properties. So you will have to create a class, which implements the SimpleImageLoadingListener.
Something in the lines of:
public class MySimpleImageLoadingListener : SimpleImageLoadingListener
{
public override void OnLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
//Do whatever you need in here.
}
}
Then you have to create an instance and pass it to LoadImage():
ImageLoader.Instance.LoadImage(imageUri, new MySimpleImageLoadingListener());

Declaring ViewModel using Constructor Injection in XAML

I'm trying out Unity and I'm having problems declaring my viewmodel in XAML. Can you help me out?
XAML:
<UserControl.DataContext>
<search:SearchBoxViewModel />
</UserControl.DataContext>
Constructor:
[ImportingConstructor]
public SearchBoxViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
{
this.regionManager = regionManager;
this.eventAggregator = eventAggregator;
}
When I try to execute I get a resolutionfailedexception.
This worked when the viewmodel had an empty constructor. It seems as if it's having problems with the constructor injection.
If I load the module like this:
var searchView = Container.Resolve<SearchBoxView>();
searchView.DataContext = Container.Resolve<SearchBoxViewModel>();
//RegionManager.RegisterViewWithRegion(RegionNames.SearchRegion, typeof(SearchBoxView));
RegionManager.Regions[RegionNames.SearchRegion].Add(searchView);
It works.
Is there any possibility to do this with xaml ( with I personally think is better )?
By the way: I'm creating an application with wpf that primarily communicates with a webservice. What should I rather user: unity or MEF and what are the big differences between the two?
Thanks,
Raphi
http://msdn.microsoft.com/en-us/library/ms753379.aspx:
Requirements for a Custom Class as a XAML Element
In order to be able to be instantiated as an object element, your
class must meet the following requirements:
Your custom class must be public and support a default
(parameterless)
public constructor. (See following section for notes regarding
structures.)
...
So, if you want to use dependencies, you should right something like:
var searchView = Container.Resolve<SearchBoxView>();
public class SearchBoxView: UserControl
{
[Dependency]
public SearchBoxViewModel ViewModel
{
get { return (SearchBoxViewModel)DataContext; }
set { DataContext = value; }
}