In universal windows apps, a new form of binding is available. Lets use this example:
<TextBox Text="{x:Bind TextContent, Mode=TwoWay}"/>
where TextContent is a simple dependency property in the same user control / or the same page. Now, the xaml compiler generates the binding by creating some .cs files in the output directory.
As the bininding is compiled into the resulting application, I want to know if there is there a way to gather information about the binding from code? Specifically, I'd like to get the property path (TextContent in this example) from my own code.
Related
I hope somebody can help.
I've spent some time researching the best way to bind an event to a ViewModel command using the MVVM pattern when developing a Universal App. I'm using MVVM Light.
As a test I'm using the SelectionChanged event of a ComboBox.
I've read a few people that have pinched the Behaviours SDK from the Windows 8.1 / WinRT framework and had some success with that. I have also included the Universal App behaviours SDK in my project and tried the following (put together from Windows 8.1 examples but using the UWP SDK).
XAML
<Page
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core" />
...
<ComboBox ItemsSource="{Binding InputQuantities}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding SomeComboBoxCommand}" CommandParameter="Foo" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ComboBox>
View Model
public RelayCommand SomeComboBoxCommand {get; set;}
However, the core:InvokeCommandAction isnt part of the Behaviours SDK and i get Invalid Type: expected type is 'Microsoft.Xaml.Interactivity.ActionCollection'. I've tried to use an ActionCollection.... but I'm not sure I know what I'm doing with that.
Ive successfully got it to work with compiled bindings and using Laurent's Blog Post:
XAML
<ComboBox ItemsSource="{Binding InputQuantities}" SelectionChanged="{x:Bind Vm.SomeComboBoxCommand }" />
View Model
public void SomeComboBoxCommand(object sender, SelectionChangedEventArgs e){//do stuff}
I know this isnt what Laurent is intending to demonstrate here and I think doing this is breaking the decoupling of the view and VM by then having to reference a UI component in my view model to get the selected item. But I've seen references to doing this during my research.
So how can I get this working using The Universal App interaction behaviours, if that's the right way to do it of course?
Update 1.
This is what I attempted to add, believing, incorrectly that I was adding the universal app behaviours SDK. I didn't notice at the time that it was targeting Windows 8.1.
However, my questions still stands: Why wont the InvokeActioncommandwork and why is it throwing the mentioned error? I will look at the other posts as soon as I get to work.
Update 2
After testing this on my works PC (exact same code as above, 1st example and the same behaviours SDK) it works fine and I'm getting the behaviour that I would expect. I need to test again on my home PC to see what has gone wrong. (Thanks to Justin XL for sticking with me)
Update 3
For completeness, after returning home I got the latest version of my project (from being checked in on my works PC) and it now also works on my home PC. I'm not sure what state my Visual Studio was in but it had sufficiently confused me enough to post this question. At least this should serve as a document on how to do what is described in the title. Thanks for all your help.
We seem to be getting this question a lot lately, in several different variants...
I'm not familiar with Universal App but is there any specific reason you're trying to use an event? WPF/Silverlight etc are designed to be data driven, all you need to do is bind the ComboBox's SelectedItem member to a property in your view model and the setter will get called whenever the user selects a new item. Often times you have to do exactly the same processing in response to other parts of your view model changing it (e.g. in Master-Child views) so having that logic in a single place generally makes for a much cleaner architecture.
Check this link: MVVM EventBinding Library ,explains about MVVM EventBinding. This purely decouples the View & View model & pass only the arguements to the command.
I am writing a win8 application and will be using the built-in resource management system: resw file and x:Uid tags in my XAML code.
So I create let's say a TextBox like that:
<TextBlock Style="{StaticResource HeaderTextStyle}" x:Uid="ResourceTest"/>
I create the corresponding resource file in my assembly with a ResourceTest.Text entry and it works fine: proper text is displayed at runtime.
Now, I would like to move all my resx files to another C# Library for maintainability. So I put the resources file in a brand new project and reference this new assembly from the main assembly.
But this causes the previous construct to fail (no text is displayed).
However, if I programmatically retrieve the resource value using the following code from inside the side assembly (called ResourcesLibrary), I get the string correctly:
static ResourceLoader resourceLoader = null;
public static string GetString(string resourceName)
{
if (resourceLoader == null)
resourceLoader = new ResourceLoader ("ResourcesLibrary/Resources");
return resourceLoader.GetString (resourceName);
}
How do I enable the x:Uid mechanism when dealing with out-of-assembly resources?
I tried a few things in the x:Uid such as ResourcesLibrary/Resources/ResourceTest but with no luck.
I had the same problem for a long time. But after testing a little bit, I solved it by writing the whole Path of the Resources in the XAML Code.
Something like this:
<TextBlock x:Uid="/ResourcesLibrary/Resources/ResourceTest" />
Unfortunately this answer came very late, but may it can help other persons.
As per my understanding you can't use x:Uid if the resources are maintained in a .resx file.
if you use .resw files you can access the strings whatever the assembly they are residing in.
they can be accessed as you mentioned in your question like this "ResourcesLibrary/Resources/ResourceTest"
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.
I am currently making a basic Windows Phone 7 application for fun, and I am trying to store string (currently only those) values in a RESX file rather than embedding them all within the XAML files directly, or even adding code to manually insert the values.
In WPF, to use the property from the RESX file, you simply map the namespace that contains the RESX:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:resx="clr-namespace:Namespace.To.Your.Resx;assembly=SuppliedIfSeparate"
and then use it:
<TextBlock Text="{x:Static resx:Strings.AppTitle}" />
But, I tried, and I've read that x:Static is simply not supported by Silverlight, and by extension, not supported in WP7 (It appears that they have provided the means, but not direct access to x:Static (French) in Silverlight 5/Mango).
I found this post describing an "AppConverter" class that is manually created to leverage similar functionality and it is currently what I am doing. The gist of the post is to create a resource within your XAML page that uses the AppConverter class for pre-specified keys, and then using that to replace the x:Static with a binding.
<TextBlock Text="{Binding Source={StaticResource AppTitle},Converter={StaticResource ResourceRetriever}}" />
It works, but it's verbose and error prone compared to the WPF implementation (a lot of copying and pasting between pages, and even controls).
What is the current best practice for this situation?
MSDN How to: Build a Localized Application for Windows Phone
I have a reasonably large Silveright 3.0 project on the go, and I'm having issues accessing a couple of custom font resources from within one of the assemblies.
I've got a working test solution where I have added a custom font as a resource, and can access it fine from XAML using:
<TextBlock Text="Test" FontFamily="FontName.ttf#Font Name" />
The test solution consists of the TestProject.Application and the TestProject.Application.Web projects, with all the fun and games obviously in the TestProject.Application project
However, when I try this in my main solution, the fonts refuse to show in the correct type face (instead showing in the default font). There's no difference in the way the font has been added to project between the test solution and the main solution, and the XAML is identical.
However, there is a solution layout difference. In the main solution, as well as having a MainApp.Application and MainApp.Application.Web project, I also have a MainApp.Application.ViewModel project and a MainApp.Application.Views project, and the problem piece of XAML is the in the MainApp.Application.Views project (not the .Application project like the test solution).
I've tried putting the font into either the .Application or .Application.Views project, tried changing the Build Action to Content, Embedded Resource etc, all to no avail.
So, is there an issue accessing font resources from a child assembly that I don't know about, or has anyone successfully done this?
My long term need will be to have the valid custom fonts being stored as resources in a separate .Application.FontLibrary assembly that will be on-demand downloaded and cached, and the XAML controls in the .Application.Views project will need to reference this FontLibrary assembly to get the valid fonts. I've also tried xcreating this separate font library assembly, and I can't seem to get the fonts from the second assembly.
As some additional information, I've also tried the following font referencing approaches:
<TextBlock Text="Test" FontFamily="/FontName.ttf#Font Name" />
<TextBlock Text="Test" FontFamily="pack:application,,,/FontName.ttf#Font Name" />
<TextBlock Text="Test" FontFamily="pack:application,,,/MainApp.Application.Views;/FontName.ttf#Font Name" />
<TextBlock Text="Test" FontFamily="pack:application,,,/MainApp.Application.Views;component/FontName.ttf#Font Name" />
And a few similar variants with different assembly references/sub directories/random semi colons.
And so far nothing works... anyone struck this (and preferably solved it)?
This code works for me:
... FontFamily="/(DLL);Component/(DIR-optional)/(Font_file)#(Font_name)"/> ...