Disabling context menu item dynamically in a WP app - windows-phone

I'm using the ContextMenu class from the Microsoft.Phone.Controls.Toolkit library to implement a custom context menu for a data-bound ListBox. The simplified part of XAML looks like this:
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="True" x:Name="contextMenuItems">
<toolkit:MenuItem x:Name="contextMenuItemPinToStart" Header="pint to start"/>
<toolkit:MenuItem Header="rename"/>
<toolkit:MenuItem Header="delete"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
I need to disable the 'pin to start' item dynamically when this context menu is about to be opened. There are some problems with implementing this:
We do not have a corresponding OnShow event.
I cannot retrieve the list item the context menu was shown for (most likely, this point depends on the answer to this previous question).
I cannot access the context menu item by its name (contextMenuItemPinToStart) to set its IsEnabled property.
Can anybody show me a suitable solution?

Related

UWP, ContentControl DataTemplate creates multiple instances of the child control

Here is the context:
I have a list view with a list of files, which can be different type.
I want to display different content when a different type of file is selected.
<ContentControl x:Name="ContentContainer" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
DataContext="{x:Bind SelectedFile, Mode=OneWay}"
ContentTemplateSelector="{StaticResource TemplateSelector}" >
<ContentControl.Resources>
<DataTemplate x:Key="GenericFileTemplate">
<mytemplates:GenericFileTemplate SelectedFilter="{Binding ElementName=Host, Path=SelectedFile}" />
</DataTemplate>
<DataTemplate x:Key="PhotoFileTemplate">
<mytemplates:PhotoFileTemplate SelectedFilter="{Binding ElementName=Host, Path=SelectedFile}"/>
</DataTemplate>
<DataTemplate x:Key="VideoFileTemplate">
<mytemplates:VideoFileTemplate SelectedFilter="{Binding ElementName=Host, Path=SelectedFile}"/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
Host is basically just the page itself, which has a dependency property of SelectedFile.
I have tried different ways to explicitly trigger the ContentControl update, including
Directly find resource in the code behind, such as
ContentContainer.ContentTemplate = FindTemplate(SelectedFile);
Using a TemplateSelector, but I have to recreate the ContentTemplateSelector each time a different file is selected
ContentContainer.ContentTemplateSelector = new FileTemplateSelector();
Both cases work.
However, one thing I notice, if I switch file type back and forth from different types. Multiple child control will be created. For example, the sequence:
select a generic file first,
the generic file template is selected,
the generic child control is created;
select a photo file
the photo file template is selected
the generic child control still respond, because the host's SelectedFile is changed, but I can ignore it
the photo child control is created
select a different generic file now
the generic file template is selected.
the first generic file child control responds (sure, I can accept it)
the photo child control responds
now a new generic file child control is created (this seems to be wrong)
so if I keep switching, the correct datatemplate is selected and assigned to my ContentControl, and then a new child control is created...
Is there a way I can make it to reuse the DataTemplate and its children if it's already loaded?
From what I can tell, no there is no way you can force the ContentControl to reuse the old DataTemplate, especially if you keep swapping out templates or templateselectors yourself instead of changing the content. This is partially because ContentControl can't know how many templates there are, so if it were to cache it, you could end up with a lot of memory consumption.
Even if you cache the datatemplate itsself, you can not cache the rendered child control because of how ContentControl uses the DataTemplate. Other controls such as ItemsRepeater however cache the actual rendered children (also called "container").

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.

How to pass an entire view in ContextMenu?

I am using context menu on a datagrid for copy/paste. But I am not getting my current view in ContextMenu's Command Parameter.In other command bindings I have passed my View name as Command parameter to get the current view status. But now I am stuck with this ContextMenu as I am not able to pass my view through it. I am using MVVM.
My snippet is
<DataGrid.ContextMenu>
<ContextMenu x:Name="_menu">
<MenuItem Header="Copy" Command="{Binding CopyCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},Path=DataContext}" />
</ContextMenu>
</DataGrid.ContextMenu>
The best way (in my opinion) is to declare your ViewModel as a static resource within your page. Then you can bind your root panel's DataContext to this static resource (getting you to where you are now). This then has the added benefit of making the binding work in your CommandParameter (by binding the parameter to a StaticResource rather than using FindAncestor).
The most probable reason why your current Binding expression isnt working is that your hit a template encapsulation boundary, but I cant be sure without seeing all of the code
<DataGrid.ContextMenu>
<ContextMenu x:Name="_menu">
<MenuItem Header="Copy" Command="{Binding CopyCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}},Path=PlacementTarget.DataContext}" />
</ContextMenu>
</DataGrid.ContextMenu>
i assume that your datagrid is in your current view

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>