How to use a resource data value in two places in XAML? - xaml

I would like to have the same text displayed as the tooltip for a Button and as the text of a TextBlock. Here's my simplified xaml:
<Button x:Uid="SweetButton">
<TextBlock x:Uid="SweetTextBlock"/>
</Button>
Right now I have two entries in my .resw file:
<data name="SweetButton.ToolTipService.ToolTip" xml:space="preserve">
<value>The same text</value>
</data>
<data name="SweetTextBlock.Text" xml:space="preserve">
<value>The same text</value>
</data>
Is there any way for me to only have one entry in my .resw file?
I've tried giving the data element two name attributes, but that's not allowed. I thought of somehow referencing the value of one data element as the value of the second data element, but I'm not sure how.

Sadly you can't re-use that resource entry while still using the x:Uid syntax as you're trying to fill in 2 complete different properties (ToolTip and Text). The universal resource system with x:Uid is very powerful and can have about any attached property in your resource file, but the downside is repeatability of resource values.
UWP XAML has somewhat different rules for x:Uid uniqueness than previous XAML-utilizing technologies used. For UWP XAML it is legal for the same x:Uid ID value to exist as a directive on multiple XAML elements. However, each such element must then share the same resolution logic when resolving the resources in a resource file. Also, all XAML files in a project share a single resource scope for purposes of x:Uid resolution, there is no concept of x:Uid scopes being aligned to individual XAML files.
Source: https://msdn.microsoft.com/en-us/library/windows/apps/mt204791.aspx
If you have a lot of duplicate resource values, you could consider using one of the 'old' ways to handle resources and bind the resources yourself.

Related

UWP MVVM XAML Dynamic UserControl Manager

I need help with a change of perspective.
I got stuck trying to approach UWP in a way I used to do in WPF regarding a MVVM pattern for managing UserControls dynamically.
I naturally tried to perform the same pattern in UWP but got stuck on various things like UWP not supporting 'x:Type' ...
Situation is; time to rethink this approach and look for a new direction. Seems I'm forced to abandon to use implicit binding in a similar fashion to the WPF pattern, using the Content property of a ContentPresenter and a VM property 'of type Object', which maintain a selected ViewModel. It was a simple and clean approach for matching up the correct View automagically with the VM set in ActiveViewModel.
the below was such a simple way of managing many views all over the place, odd MS not fixing this? But, back to the big Q: what now in UWP!?
<ContentPresenter Content="{Binding ActiveViewModel}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:OneViewModel}">
<local:OneView />
</DataTemplate>
<DataTemplate DataType="{x:Type local:TwoViewModel}">
<local:TwoView />
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
What Shall I do instead of this!? Anyone found a new efficient way of doing it? I got stuck in my stubborn mind and need someone to kick my butt so I go forward. Getting to old to change, but due to this profession it seems I constantly have to. :)
Looking at the DataTemplate documentation, there's a paragraph explaining the situation which you are trying to figure out.
For advanced data binding scenarios, you might want to have properties
of the data determine which template should produce their UI
representations. For this scenario, you can use a DataTemplateSelector
and set properties such as ItemTemplateSelector to assign it to a data
view. A DataTemplateSelector is a logic class you write yourself,
which has a method that returns exactly one DataTemplate to the
binding engine based on your own logic interacting with your data. For
more info, see Data binding in depth.
Here, you have an example on how you can select distinct DataTemplate for items in a control such as a ListView based on defined conditions.
Your situation is a bit different from the one described above, but the solution should be within what is explained above.
Create a class which derives from DataTemplateSelector, and override the SelectTemplateCore methods exposed by it, where you define the logic of what DataTemplate should be selected for the specific presented object.
This Derived class should expose properties of type DataTemplate, which identify each single DataTemplate template object, you pretend to be able to choose from.
Just as in the example, you are probably better of by defining the DataTemplate resources on an higher level object, such as the Page itself.
Instantiate your DataTemplateSelector Derived class in XAML as a resource and set each of the properties exposed above of type DataTemplate to the analogous DataTemplate static resource.
Utilize the ContentTemplateSelector dependency property, by setting it your custom DataTemplateSelector.
With this logic, it should be possible to have your ContentPresenter decide correctly between which DataTemplate it should choose from, based on your required UI logic.

Default XAML page and New XAML page in Xamarin Forms is not identical

I am new to Xamarin development. I created new Xamarin XAML App(Xamarin.Forms Portable). In Portable Project there where MainPage.Xaml by default. To create MVVM Model I created three new Folders- Views, ViewModels, and Models. Now I added new MainPage.Xaml in Views folder and was going to delete the default MainPage.Xaml page. But here I see some difference in both pages. The default MainPage.Xaml have xmlns:local="clr-namespace:Test" but the new MainPage.Xaml does not. Again the new MainPage.Xaml have <Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" /> but the default one does not. The screenshots are:
What does these MarkUp mean.Why there is a difference. Does something needs to be changed. Can I delete the default MainPage.Xaml or should i copy it in Views.Does I need to copy the Markup from the default Page to the new one. If so why?
Thanks in advance
Both pages are identical, and will display in the same way.
On the second, there's an additional Xml namespace declaration:
xmlns:local="clr-namespace:Test"
It's only a declaration. You could remove it, or add it to the other page without effect. It's purpose is to be able to reference custom views declared in the current assembly and in the namespace (c# namespace, this time) Test, like this:
<ContentPage
...
xmlns:local="clr-namespace:Test"
x:Class="Test.MainPage">
<local:MyAwesomeView />
</ContentPage>
Awesome that you have decided to start with Xamarin and Xamarin.Forms!
While I understand you might be having these questions, this is some very basic XAML knowledge. The short answer is: you don't need to worry about it.
The long answer:
The reason that there is a difference in these pages is simply because it's just a template and whoever at Xamarin created the template for the project can be a different person than who created the template for a new XAML page. So they solved it different ways. Or maybe he had a good/bad day, who knows.
The Label in the first page is simply there to show you how to get started and so you won't start with an empty screen.
The extra namespace xmlns:local="clr-namespace:Test" is actually redundant in this new page but is already there so you can use the classes in your project.
It is actually the equivalent of the using list at the top of your classes. So whenever you need something from a different namespace you have to declare it there. So if you create a folder 'Controls' you can add a attribute xmlns:controls="clr-namespace:Test.Controls".
Note how I changed local to controls, this is the prefix you will use to define your instance. Also I have added the right namespace Test.Controls. Now if you want te show something on screen, in your XAML from the controls namespace, go like this:
<ContentPage xmlns:controls="clr-namespace:Test.Controls" x:Class="Test.MainPage">
<!-- some stuff here -->
<controls:ReusableControlHere />
</ContentPage>
Where ReusableControl can be your own version of a Label, Button or virtually anything.

Why have attached properties been added to XAML?

I have looked at various examples and read about attached properties. However it is still not clear to me why they are required or better. Look at this example:
<DockPanel>
<CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>
DockPanel.Dock is an attached property and it is clear what the intention is: not very element should have or need an individual property that would allow it to define its docking behavior. Same goes for grid's row and columns definitions. But why not express things like this instead:
<DockPanel>
<Docked Location="Top">
<CheckBox>Hello</CheckBox>
</Docked>
</DockPanel>
Similar would be possible for grids with row and column tags.
Was this a pure design decision or are there other reasons that make attached properties the better or the only solution?
Your example might be applied for just one case, even frequent, but you should not rely on just one attached property.
Suppose, for instance, that you wish to mark more than just one attached property, as follows:
<DockPanel>
<CheckBox DockPanel.Dock="Top" TextBlock.FontSize="16">Hello</CheckBox>
</DockPanel>
How messy would be the equivalent "encapsulated" way?
I myself would add another viewpoint, despite is just mine. The XAML notation often denotes the objects structure: an element represents a class (instance), whereas an attribute a property. Your pattern would fight against the ability to set a property as follows:
<DockPanel>
<DockPanel.RenderTransform>
<ScaleTransform ScaleX="2" ScaleY=3" />
</DockPanel.RenderTransform>
</DockPanel>
This is a particular element pattern which denotes an alternative way to define a property (e.g. RenderTransform) content (i.e. the actual transform instance).
UPDATE: I'd also add another thing about what should be inserted as child of a certain container (the DockPanel in your example). The "Docked" should be an actual child or just a virtual container being not part of the visual/logic tree? Then , supposing walking up the visual/logic tree, should you find this element or not? If not, in which way should you get the "Docked" value?
Now, I am not sure whether my answer is satisfying you, but...feel free to specify better what you don't like in the attached-properties pattern, and maybe you'll reach the point!

Can I apply "StaticResource" to element in run-time?

Can I apply "StaticResource" to element in run-time?
I know I can use "StaticResource" to element in xaml files. But, I want to know how to use it from C# (code-behind).
A StaticResource is a static defined resource, usually defined in the <X.Resources> element, for any element or page.
In C# you simply access it with X.Resources["MyResource"] like you should do {StaticResource MyResource}.
Not really with the same meaning. StaticResources are "static" in the sense that their value is resolved during Xaml parsing. The XamlParser will resolve the resource by examining the resource dictionary the ancestor FrameworkElement Resource properties that are also in the same xaml and then the Application.Resources if necessary.
If you happen to know where to find the resource you want to assign using C# code then it is as simple as in Claus' answer. However if you only know the name of the resource but not which dictionary its found in then its much tricker.
It is possible to write a routine (you can probably find one in SO or elsewhere on the web) that you can use to hunt up the Visual tree using the VisualTreeHelper looking at all the Resource properties along way. You could probably get away with this but be aware that this may search more dictionaries than the original Xaml version would and its possible for you to get some unexpected value.

XAML tag list reference

As the question suggests I'm simply looking for a XAML tag list reference. I've banged the obvious queries in Google/SO but not found what I am looking for yet. Any useful links welcome.
There's a WPF Binding Cheatsheet and another XAML for WPF Cheatsheet which might help, but really the "tags" in XAML are just the properties of the classes.
There isn't such a thing as a xaml tag list.
XAML is just a declarative way to instantiate .Net classes. Class names are elements in XAML and properties on the class are attributes or attribute elements using dot notation.
Tags in XAML only mirror the types in one or more assemblies that are bound to a particular XAML namespace.
There are however a specific set of elements that are specific to XAML in itself and are not related to any particular .Net assembly, those are usually in the x: namespace, more info here: XAML Namespace (x:).
There is no such thing as the XAML tag list since XAML is an open system.
There are, however, standard vocabularies. Rob Relyea's Blog is a good place to keep track of the standardization around these vocabluaries. For example, this is an entry for the Silverlight XAML vocabulary.
With WPF the XAML elements map to the classes like StackPanel. MSDN seems to give XAML examples for many of the controls.
There are XAML-specific conventions about representing things like complex properties and bindings. However, there is no definitive list of XAML tags. XAML tags are actually mapped to WPF objects. For example, <Button> is just a XAML representation of the System.Windows.Controls.Button class and the attributes allowed on the <Button> tag are the public properties of the Button class.
There should be several WPF cheatsheets available soon on http://www.devsheets.com (since around September 2011) ... You can download it there, and also buy printed versions with more detailed information on them (not all content fits in publicly available pdf, because pdf would not be readable if printed on paper without high quality print ... that is why we also decided to sell high quality laminated cheatsheet prints in addition to their free versions)