What's the DataContext of the Header elements inside a Hub control? - xaml

I have started to develop for WP 8.1 using Windows Runtime recently, and I have faced a... "problem" that I don't seem to understand.
The application I am currently developing uses a Hub control, and I would like to tweak its header's appearance slightly. To do so, I changed the HeaderTemplateattribute of the Hub control. However, as I tried to localize the textual content of the header (note that this is WinRT, the localization process is slightly different from the process in WP8 and can be found here), I "accidentally" fixed the problem by making the template like this:
<Hub.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
Foreground="Red"/>
</DataTemplate>
</Hub.HeaderTemplate>
I don't understand why it worked, though. When you do data binding like this (just using the expression {Binding}), doesn't the element get the same DataContext as its father? What's happening under the hood? Who's the parent element of the TextBlock, after all?
Thanks in advance.
EDIT
As igrali asked, here is a more complete view of the XAML:
<Page ...
DataContext="{Binding Data, RelativeSource={RelativeSource Self}}">
<Grid Background="#FFF6DB">
<Hub Name="MainPageHub"
x:Uid="MainPageHub"
Margin="0,27,0,0">
<Hub.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"
Foreground="White"/>
</DataTemplate>
</Hub.HeaderTemplate>
...
Then, in the /Strings/en-US/Resources.resx, I have a "MainPageHub.Header" property set to "foobar" (just an example), and what I get as a header is actually "foobar" (which is what I wanted, but even so it seems confusing!).

As Tim Heuer explains it here
Notice the x:Uid value here. This now maps back to the key in your
RESW file. Anything with that starting key will have properties
merged into it. So we can have a key in our RESW for “Text” using the
key name MyTextBlock.Text with a value of “Hello World” and the
runtime will do the replacement for you. This applies to properties
other than text (i.e. width) as well as attached properties.
All I can add is - notice the x:Uid. It's MainPageHub. In the localized resource file, you have a MainPageHub.Header. This means that the value of the resource string will be set to the Header of the control which has the x:Uid set to MainPageHub.
So, now that it's clear how the Header is set - there's still the binding part. Well, considering you have a different template for the Header, it needs to do the {Binding } part to actually get the value of the header which is set through the resources.

Related

Multi binding in UWP

I want to display a textblock with latitude and longditude. In my model, the lat and lng are two variables, so I need to combine them, preferably with stringformat as this answer suggests. Unfortunately it doesn't seem like multi binding is supported in UWP applications.
That leaves me with a couple of options.
Create two text blocks that are bound to each variable and align them next to each other. I'm not sure if i need two extra textblocks to be able to display "lat" and "lng" in front of the values. And then an third label displaying "Position" in front of that again. This answer states that there is no stringformat property for Binding. A total of five textblocks is too much in my opinion.
<RelativePanel>
<TextBlock x:Name="EquipmentLatTextBox"
Text="{Binding Equipment.lat}"/>
<TextBlock x:Name="EquipmentLngTextBox"
Text="{Binding Equipment.lng}"
RelativePanel.RightOf="EquipmentLatTextBox"/>
</RelativePanel>
Create a value converter.
This also seems very unnecessary. I get the point of using converters to convert across data-types, but for concatinating strings there should be a buildt in property.
Create a property in the view model that returns a string of the values as it should be displayed. This seems like the best option as the method is not in the model, but i still think that i should be able to do this in the xaml markup.
Is there a better way to do this?
This can be solved by using runs. It's actually a lot easier to achieve this in UWP than with multi-binding in WPF. A TextBlock item can consist of several "runs" of text which can bind to different properties. The runs will behave like inline elements. Each run can have text directly between the tags, or as a text property. Each run-element can also have independent styling.
Documentation for the TextBlock class
For the example i provided in my question, i ended up formating it like this
<TextBlock x:Name="LocationTextBlock">
<Run FontWeight="Bold">Location: </Run>
<LineBreak />
<Run>Lat: </Run>
<Run Text="{x:Bind ViewModel.Equipment.Lat}"></Run>
<Run> Lng: </Run>
<Run Text="{x:Bind ViewModel.Equipment.Lng}"></Run>
</TextBlock>
The result looks like this
Location:
Lat: 00.000 Lng: 00.000
No, the Universal Windows Platform currently doesn't support multi binding. The best solution for you is indeed creating a dedicated property in the view model or alternatively using the two TextBox controls. As compared to WPF the binding syntax in UWP is more limited to ensure the best performance possible.
You could also consider using the x:Bind syntax to ensure strongly-typed and optimized bindings, which were introduced with UWP.

How to Export SketchFlow (Blend for Visual Studio 2013) Project correctly

I have a SketchFlow Project, which is a prototype of an application that we are designing, and I am at the stage that I would like to export the project to another format for sharing.
The first thing that I tried was:
File | Export | Export as Images...
However, after this had finished running, I only had 6 screenshots. I have over 30 screens in the prototype. Does anyone have any idea why all screens are not exported?
I then tried:
File | Export | Export to Microsoft Word...
And this results in the following error:
Any thoughts on what is happening here? I have tried looking for a log file, but I couldn't find one.
The final option which I have tried is:
File | Export | Package SketchFlow Project...
Which seems to work perfectly. However, I would like to embed the images into a design document, and don't really want to have to go through taking screenshots manually, which will be the last resort.
Update 1
Ok, seems like it is certain screens that are causing the problem. When I do the "Export to Microsoft Word..." option, and choose only the first screen, the Word document exports correctly. However, when I add in another screen (one of the ones that wasn't included in the "Export as Images" method, I once again get the error that I showed the screenshot of.
Update 2
As requested in comments, the layout of the pages are as follows.
Header Component - which shows overall title of the application, and some common buttons.
Navigation Component - Menu Structure for all top level pages
All screens, with the exception of the Login/Register page, have the Header and Navigation Component added to them
Some screens are using Sample Data to populate elements on the page. Others are just simple controls, laid out on the page.
Update 3
Ok, I have just done a pretty comprehensive test, and when using "Export to Microsoft Word..." if I exclude all the screens that use Sample Data, the export completes successfully. As soon as I include any screen with sample data, it throws the exception. I can only assume that the "Export as images..." is failing silently when it hits the first screen that has Sample Data in it.
This is a bug. It's related to resource resolution. You may be able to work around by making the ItemTemplate property local instead of the default resource.
For example, with a repro built using the databinding showcase instructions - http://www.microsoft.com/en-us/showcase/details.aspx?uuid=db8a7eb6-3039-4008-a9f2-f5c910bcddf3
Replacing the ItemTemplate
<ListBox HorizontalAlignment="Left" Height="330" Margin="73,40,0,0" Style="{DynamicResource ListBox-Sketch}" VerticalAlignment="Top" Width="535" ItemsSource="{Binding Collection, Source={StaticResource snowboardData}}" DataContext="{Binding Source={StaticResource SampleDataSource}}" ItemTemplate="{DynamicResource ItemTemplate}"/>
With
<ListBox HorizontalAlignment="Left" Height="330" Margin="73,40,0,0" Style="{DynamicResource ListBox-Sketch}" VerticalAlignment="Top" Width="535" ItemsSource="{Binding Collection, Source={StaticResource snowboardData}}" DataContext="{Binding Source={StaticResource SampleDataSource}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Images}" HorizontalAlignment="Left" Height="64" Width="511"/>
<TextBlock Text="{Binding Text}" Style="{DynamicResource BasicTextBlock-Sketch}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Allowed me to export to Word.
This has been reported to Microsoft and should be fixed in a future VS/Blend update.
After some back and forth offline with #shawty, we believe we have come up with the reason why the export is failing. It is not specifically tied to doing an export when Sample Data is being included, but more specifically when using Sample Data with a Sketch Control.
This is what I did to verify this...
Created new Sketch Flow Project
Added ComboBox control to the page
Added DataSource to the Data tab
Added Collection Property
Added Simple Property to Collection
Edited Data to include some sample data
Bound the ComboBox to the sample data
Ran the application to make sure it is working
Ran the Export to Microsoft Word...
Everything worked correctly
I then repeated the "exact" same process using the ComboBox - Sketch control, and the Export to Microsoft Word... failed to function, displaying the error message shown in question above.
The suggested workaround from #shawty is as follows:
"The sketch controls are functionally exactly the same as the OOTB ones under the hood, they just have a different dictionary of styles applied to them, my suggestion would be to take the OOTB controls, add your own set of styles to them to give them a similar look and feel. You'd only have to define the resource dictionary once at application level for each appropriate control (Button, Label, Datagrid and any others you use) , and the entire application will just maintain the same look and feel."
While this is a perfectly viable solution, it doesn't take anyway from the fact that I believe that this is a bug in the Sketch Flow application. I just don't know where to raise the bug, as there doesn't seem to be a section on Microsoft Connect to raise a bug about Blend, and/or Sketch Flow. If anyone knows where I can take this, I would love to hear about it.

Order of bindings in Windows Phone 8

I am facing this issue regarding data binding and binding in a converter while developing a Windows Phone 8 app.
I am trying to send the button to a converter so I can access all of its properties using the following code
<Button Content="{Binding OwnBoard, Mode=OneWay}" Grid.Row="0" Background="{Binding RelativeSource={RelativeSource Mode=Self}, Converter={StaticResource BoardToBackConv}}" />
When I hit the break point in the converter I have the button as the binding object, but the Content property of the control is Null. I need to access the object stored in the Content property.
As far as I know, because of the order of the bindings, the Content property should already contain a value.
Any idea how to make this work?
I have managed to understand why what I want to do is not going to work.
Keeping it short, the converter is executed during the InitializeComponent() call, and at that time the other binding was not done, because there is not DataContext for the view yet.

Windows 8 XAML Multilingual Translations

I've used the Multilingual Toolkit to translate my app and have been testing it using pseudo-language. It works fine for strings I have translated in code (C#) but I can't work out how to make it so that the tag in XAML is automatically translated.
I've been using http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh965329.aspx as a tutorial but I can't figure it out. I've also searched on Google but still no luck.
For example, I created a "Watermark" text box (which inherits from TextBox which shows some text in by default it the user has not entered any text and the item does not have focus. The XAML looks like this (I replaced generic positioning stuff with '...'):
<local:WatermarkTextbox x:Name="TitleTextBox" Watermark="MainPage_EnterATitle" ... Style="{StaticResource TextBoxStyle1}" />
As you can see it is setting a property called Watermark with a 'tag' of the resource name that is being translated using the Multilingual tool. I'm not sure how to get this to automatically translate.
Another example is using the bottom app bar buttons:
<Button x:Name="bottomAppBar_unpinFromStartButton" AutomationProperties.Name="MainPage_UnpinFromStart" Style="{StaticResource UnPinAppBarButtonStyle}" Click="bottomAppBar_unpinFromStartButton_Click"/>
And I can see in the link above that it says:
MediumButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name
But I'm not really sure where this is meant to go.
Even with a button, which seems like it would be the simplest to translate I can't get it to work. The XAML is:
<Button x:Name="RemovePhotoButton" x:Uid="MainPage_RemovePhoto" Content="" HorizontalAlignment="Center" Margin="222,0,974,78" Grid.Row="1" VerticalAlignment="Bottom" Width="170" Height="45"/>
But when ran in the app or viewed in the designed the button stays blank, with no text on it.
The Resources are set up like this:
And it is filling the translated documents fine:
I am able to translate it in C# using the code from the link above, just not using XAML.
Just wondering if anybody could help me out or point me in the right direction to solve this.
Thanks
First what i think is missing in the name of your resources is the property that you want to set. While never used it myself, i would understand it like this:
Your xaml needs to be changed to
<local:WatermarkTextbox x:Name="TitleTextBox" x:Uid="MainPage_EnterATitle" Watermark="" ... Style="{StaticResource TextBoxStyle1}" />
And your resource needs an entry with the key
MainPage_EnterATitle.Watermark
And about the part with the
MediumButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name
This is only used if the referenced property is an attached property. Like if your Watermark property would be attached not part of the control. But in your case its not important.

Windows 8 bottom app bar

I've been trying to get an App bar implemented in a WinRT metro app (C# / XAML), but don't know where to begin. I've tried using the <ApplicationBar/> tag and I get a Type not found error.
There's no help online, could someone update this post with the answer so that it'll serve as a reference to other programmers as well?
There's only a JavaScript sample which isn't of much help.
This should work:
<AppBar
VerticalAlignment="Bottom">
<Button
AutomationProperties.Name="Play"
Style="{StaticResource PlayAppBarButtonStyle}"
Command="{Binding PlayCommand}" />
</AppBar>
– you would put that in the layout root grid of your page.
*EDIT
Note: According to documentation - you should put it in Page.BottomAppBar property, although at least in Windows 8 Consumer Preview - it works fine when used in any Grid, which is convenient if your UI isn't tightly coupled to a Page control.
*EDIT 2, response from MSFT:
The recommended approach is to use the Page.BottomAppBar/TopAppBar properties.
There are known hit-testing issues in the Consumer Preview if AppBars are added without using these properties
The AppBars do not use the proper animations if they are added without using these properties
If AppBars are added as children of arbitrary elements then it's easier for multiple controls to attempt to create/modify AppBars, resulting in an inconsistent user experience
*EDIT 3
The CustomAppBar in WinRT XAML Toolkit can be used anywhere, animates based on Vertical/Horizontal-Alignment, can have other content overlaid on top of it and also has a CanOpen property that allows to block it from opening.
<Page.TopAppBar>
<AppBar>
<TextBlock x:Name="TextBlock1" Text="Sample Text" Margin="0,0,0,0" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</AppBar>
</Page.TopAppBar>