UWP Relativepanel bound to UiElement doesn't work like RelativePanel with propertie = UiElement - xaml

We are developing a Windows10 Universal App (UWP). We have huge issues related to how RelativePanel behave depending of syntax and pc.
We have dynamic data response from a web service and we have to display a dynamic structure of UI controls to render the GUI.
We are trying to use RelativePanels with child elements composed of ItemsControls rendering different type of sub data (Addresses, Phones, etc..).
The ItemTemplate of each ItemsControl' item is a Template composed of a RelativePanel.
Now, the weird stuff happened differently between design and runtime.
At design time, when we want to set Target UIElement of the RelativePanel, we can use the following syntax:
Ex: RelativePanel.Below="EntryMobileNumbers" or
Ex: RelativePanel.Below="{Binding ElementName=EntryMobileNumbers}" />
They are supposed to both work but they don't.
For some RelativePanels’ child elements, if we use the first syntax, the xaml designer bugs and display weird error message
about “value must be of type UIElement”.
Looked on forums for this type of Xaml error and it seems for some developers it’s better to use the second syntax with the Binding.
The good side of it is with that the design is not displaying the squigglys and the error BUT the pb is at Run-time;
the result is wrong and some elements are overlapping.
With syntax 2
With syntax 1
We have also different issues between dev pc’s. With the VS2015 Enterprise installed on all pc’s,
some are displaying squigglys or crash the Xaml Designer with Syntax 1 and some are not.
We also tried to update VS2015 with yesterday’s RC1. It fixed the issues on one of the Pc and not on the others.
PS. All samples out there are very simple. I would very happy to see a "real life" application.
Like e.g. Money from the store to see how layout are managed

RelativePanel.Above="{Binding ElementName=SubTitleDesktop}"
instead of
RelativePanel.Above="SubTitleDesktop"
and it will helps you get rid off errors

Related

Design-time data not showing when creating a UWP MVVM Light project

When creating a MVVM Light UWP app, I am not able to get programmatic design time data working via my View Model. I believe this may be due to Visual Studio 2015 adding in the property names of the bindings in the designer instead. I have confirm this be creating a blank MvvmLight (Win10Univ) app in the project templates (MVVM Light 2015 for VS2015 - Version 5.2.0.0) and it clearly shows "WelcomeTitle", the name of the property instead of "Welcome to MVVM Light [design]" that is set up in the DesignDataService class.
MVVM Light Main Page capture in designer showing incorrect design time data
When seeing this problem in my own project, I am using something like this in my View Model:
if (this.IsInDesignMode)
{
// Load design time data when in design mode
this.Duration = "2 HRS 13 MINS";
}
I am then binding to the property in my View with the data context set as follows:
<Page.DataContext>
<Binding Path="FooBarPageViewModel" Source="{StaticResource Locator}" />
</Page.DataContext>
Now, normally the above is all you need to do as per the MVVM Light project template app, but I have tried to following with no success:
d:DataContext="{Binding FooBarPageViewModel, Source={StaticResource Locator}}"
I have also tried using x:Bind, but still see the same problem.
So does anybody know how to resolve this problem or has come across something similar?
Note: This issue may not be just related to MVVM Light and could instead be a UWP platform issue.
Okay, so building the template MVVM Light UWP app in x86 architecture allows you to see the design time data in the Visual Studio designer. However, a few of points:
When in x86 mode, you have to enable the project code button in the designer to see the design time data.
If you have a combination of x:bind and runtime binding in the XAML page using x86 then the designer crashes. You can disable the project code in the designer to fix the crash, but then design time data won't work again.
When in x64 mode, it seems you can't enable the project code button, thus resulting in this original problem.

EventToCommand binding with parameters in portable view models

I am implementing a view model that is shared by applications on multiple platforms. I am using MvvmCross v3 that has its own MvxEventToCommand class, but I believe the challenge is the same for other frameworks like MVVM Light. As long as the event is used without parameters, the implementation is straightworward, and this is the case for simple interactions like tapping the control.
But when the command needs to handle event arguments things become more complicated. For example, the view model needs to act on certain scroll bar changes (and load more items in the associated list view). Here is the example of XAML:
<cmd:EventToCommand
Command="{Binding ScrollChanged}"
CommandParameter="{Binding EventArgs}" />
(MvvmCross uses MvxEventToCommand, but the principle is the same).
Then in my model I can have the following command handler:
public ICommand ScrollChanged
{
get
{
return new RelayCommand<ScrollChangedEventArgs>(e =>
{
MessageBox.Show("Change!");
});
}
}
(MvxCommand in MvvmCross).
The problem is that ScrollChangedEventArgs is platform specific and this code simply will not compile in a portable class library. This is a general problem with any command that needs not only a push when an event was fired but requires more specific event details. Moving this code in platform-specific part is silly because it more or less kills the concept of portable view models and code-behind-free views. I tried to search for projects that share view models between different platforms, but they all use simple events like "Tap" with no attached event details.
UPDATE 1 I agree with Stuart's remark that view models should only deal with higher level abstractions, so I will rephrase the original concern: how to map results of low-level interactions to a platform-neutral event that triggers a business logic command? Consider the example above: the business logic command is "load more items in a list", i.e. we deal with a list virtualization where a limited number of items from a large collection are loaded initially, and scrolling down to a bottom of a list should cause additional items to be loaded.
WinRT can take care of list virtualization by using observable collections that support ISupportIncrementalLoading interface. The runtime detects this capability and automatically requests extra items from a respective service when the user scrolls down the list. On other platforms this feature should be implemented manually and I can't find any other way than reacting on ScrollViewer ScrollChanged event. I can see then two further options:
Place OnScrollChanged handler in a code-behind file and call the portable view model higher level event (such as "OnItemsRequested");
Avoid code-behind stuff and struggle to wire the ScrollChanged event directly to a view model, then we will need to remap the platform-specific event first.
As long as there is no support for second option, putting event handler in code-behind file is OK as long as it is done for the sole purpose of event mapping. But I would like to investigate what can be done using the second option. MvvmCross has MapCommandParameter class which seems to be able to help, so I wonder if I should exploit that one.
UPDATE 2 I tried MapCommandParameter approach, and it worked allowing me to insert a platform-specific adapter that would map low-level events to view model-specific commands. So the second option worked without any struggle. Stuart also suggested listview-subclassing so there is no need to care about scrolling events. I plan to play with it later.
I agree that viewmodel commands should normally be expressed in terms of viewmodel concepts - so it would be 'strange' to send the viewmodel a command about the scrollbar value changing, but it might be ok to send the viewmodel a command about the user selecting certain list elements to be visible (which she does via scrolling)
One example where I've done this type of thing previously is in list selection.
I originally did this across multiple platforms using a cross-platform eventargs object -
https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross/Commands/MvxSimpleSelectionChangedEventArgs.cs
this was then used on WindowsPhone (for example) via an EventToCommand class like https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.WindowsPhone/Commands/MvxSelectionChangedEventToCommand.cs
However... I have to admit that this code hasn't been used much... For list selection we have instead mainly used selecteditem binding, and there simply haven't been any apps that have needed more complex parameterized commands (so far) - you might even need to go back to very old v1 mvvmcross code to find any samples that use it.

Page Navigation in Windows 8 XAML (without using code behind)

For my windows 8 application i am trying to navigate between pages with out using code behind.
For example, i have one image in my UI without creating tapped event for that image i need to navigate to another page,
<Image Source="ms-appx:///Assets/Logo.png" Width="155" Height="110" Tapped="{ // Navigation method here }"/>
Is it possible to navigate between pages like this...? If possible, how can i get this to work??
XAML is just a declarative language without action part so code behind is an essential part of it.
All interactions work via events and event can be handled in a code behind only. So what you want is not possible with XAML(at least with WinRT XAML).
If you are asking if you can specify the code inside the .xaml file, then no, that is not possible.
If you are asking if you can avoid adding code to the .xaml.cs file, then yes, that is possible. You will still need to specify a method but it can even be done as a simple lambda. You will need to use the Command hooks rather than the Event Hooks, e.g.
<Button Command="{Binding GoConnectionCommand}" ... />
The code for this command is usually defined in the ViewModel as part of the MVVM pattern, and Josh Smith explains it far better than I will.
AlSki mentioned using a ViewModel. Although technically the ViewModel is not part of the "code behind" for the XAML file, it's still code and I believe you were asking for a no code solution.
ixSci is correct that there is no way to do this out of the box without code behind in WinRT XAML.
In full WPF it's possible to do this using a behavior called NavigateToScreenAction. You can read about it here. Unfortunately behaviors don't ship out of the box with WinRT, but they can be added back in by an open source project called WinRtBehaviors.
There is no NavigateToScreenAction behavior for WinRT, but one could be created. There is a good article on creating behaviors with the library here. It will obviously require code to create the behavior, but after it's created you could use it in XAML without any code.
Really, the short answer is it's not possible to navigate without code on WinRT.
Dev support, design support and more awesome goodness on the way: http://bit.ly/winappsupport

Metro equivalent for HeaderedItemsControl

Converting a WPF application from .Net 4.0 to Metro.
It uses HeaderedItemsControl in various places.
I have not been able to find that control or a replacement candidate in Metro (Windows.UI.Xaml namespace)
So what is the recommended control in Metro to provide the functionality of HeaderedItemsControl?
You could easily create one by deriving from ItemsControl and adding a few simple dependency properties. You can see which properties are present in the WPF version here. You might not need all of them, but from a quick glance I can see a Header property which is just an object type. You would put a ContentPresenter in your HeaderedItemsControl's ControlTemplate and bind its Content to the HeaderProperty using TemplateBinding. Then bind the HeaderTemplate to the ContentTemplate of the ContentPresenter, etc.
Not sure how useful it is though to port WPF XAML code directly to WinRT. You're just asking for trouble in terms of code compatibility, but also porting a likely desktop-designed UI to a more touch-centric world.

WP7 Silverlight: Data binding with the same XAML at design & runtime

I'd like to use the same data at design and runtime in my WP7 application. The relevant part of the XAML looks like this:
<phone:PhoneApplicationPage ...
d:DataContext="{d:DesignData Source=data.xaml}"
DataContext="{Binding Source=???}"
This way I can see the data at design time. Is there a way to use the same data at runtime?
Was not aware of the existence of d:DataContext. I dare to say:
<phone:PhoneApplicationPage ...
d:DataContext="{d:DesignData Source=data.xaml}"
DataContext="{Binding Source=data.xaml}"
--- Edit added -------------------
Well... checking here and there found that, as expected, "DesignData" is not the same as "Binding" (I was misreading this, sorry). "DesignData" has the ability to instance, at design time, an object based on a xml file and this has no effect at runtime. The Binding we are try to build will never work, as its purpose is to use already instanced objects.
When you run the default template for panorama applications it instances its own data (check the code for MainViewModel.cs)... and that's why it shows is different from that in the xml file. All you have to do is, manually, open the xml in the "LoadData" method and load the file data so you can display the same at runtime and design time.