How can I get an element from within a ListViewItem's ItemTemplate? - c++

I have a ListView that uses a custom ItemTemplate (doesn't everyone?):
<ListView>
<!-- ... -->
<ListView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<MyGreatControl Thing="{x:Bind}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
MyGreatControl today has extensive keyboard handling code built-in, but due to some refactoring, I need to move the actual handlers to the ListView itself. However, I don't want to move all of the code in MyGreatControl to the ListView (for many reasons).
If I have an arbitrary ListViewItem (which, for example, I can get from an event handler), how can I access the MyGreatControl instance in its DataTemplate?
MyGreatControl^ GetMyGreatControlFromListViewItem(ListViewItem^ listViewItem) {
// ???
}
Disclaimer: I work for Microsoft.

You want to use ContentTemplateRoot!
MyGreatControl^ GetMyGreatControlFromListViewItem(ListViewItem^ listViewItem) {
return safe_cast<MyGreatControl^>(listViewItem->ContentTemplateRoot);
}
This also works for any arbitrary element—if you have a StackPanel, for example, ContentTemplateRoot will return the StackPanel instance you want:
<ListView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<StackPanel><!-- This is what you get! -->
<TextBlock Text="{x:Bind}" />
<Button Content="Foo" IsTabStop="False" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
You can then use normal visual tree navigation to find Children, etc.

Related

Which UWP controls are supported as XAML Islands in a Desktop application?

I'm playing with UWP in plain Win32 projects, reading more about C++/WinRT here, the XamlReader, the events and the control collection.
For this I 've made a small library which enscapulates such a control into a plain HWND and I can set the text using WM_SETTEXT.
Is there documentation on which of these controls are available in plain Win32 and which arent?
For example, this markup works:
<StackPanel x:Name="LayoutRoot" Margin="10">
<Button x:Name="btn1" Content="Hover to Click"
Click="OnClick1" ClickMode="Hover"
Margin="5" Width="150"
HorizontalAlignment="Left"
Foreground="Green"/>
<TextBlock x:Name="text1" Margin="5,8,0,0" />
<Button x:Name="btn2" Content="Press to Click"
Click="OnClick2" ClickMode="Press"
Margin="5,5,5,5" Width="150"
HorizontalAlignment="Left"
Foreground="Blue"/>
<TextBlock x:Name="text2" Margin="5,8,0,0" />
<Button x:Name="btn3" Content="Reset"
Click="OnClick3" ClickMode="Release"
Margin="5,5,5,5" Width="150"
HorizontalAlignment="Left"/>
<TextBlock x:Name="text3" Margin="5,8,0,0" />
</StackPanel>
Generally, many controls work. However some, like WebView, don't:
<WebView x:Name="webView1" Source="http://www.contoso.com"/>
When using XamlReader::Load to load this, it throws {value=0x802b000a } winrt::hresult E_XAMLPARSEFAILED:XAML parsing failed.
Do I miss something? Are there some controls not yet available? Do I need some additional dependency?
Thanks a lot.

UWP: Set text to bold in TreeNode

I am following Microsoft's documentation to implement a TreeView in a Universal Windows Platform app in C++. I have successfully been able to create a tree view with one node using the following codes:
XAML:
<TreeView x:Name="treeSolution"></TreeView>
C++:
TreeViewNode ^treeNode = ref new TreeViewNode();
treeNode->Content = "Hello";
treeSolution->RootNodes->Append(treeNode);
Now, I want to set the text to bold. I tried the following:
TextBlock ^textBlock = ref new TextBlock();
textBlock->Text = "Hello";
textBlock->FontWeight = Windows::UI::Text::FontWeights::Bold;
treeNode->Content = textBlock;
treeSolution->RootNodes->Append(treeNode);
The code displays Windows.UI.Xaml.Controls.TextBlock instead of Hello in bold.
The documentation says that In Windows 10, version 1803, you have to retemplate the TreeView control and specify a custom ItemTemplate if your content is not a string. It then gives a complex example using the Music and Picture library.
Could somebody provide a simple example of how to display the text in bold? Thanks.
You have to provide a custom style for the whole control in XAML to be able to set the TreeViewItemDataTemplate:
<DataTemplate x:Key="TreeViewItemDataTemplate">
<Grid Height="44">
<TextBlock
Text="{Binding Content}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
FontWeight="Bold" />
</Grid>
</DataTemplate>
<Style TargetType="TreeView">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<TreeViewList x:Name="ListControl"
ItemTemplate="{StaticResource TreeViewItemDataTemplate}"
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
CanDragItems="True"
AllowDrop="True"
CanReorderItems="True">
<TreeViewList.ItemContainerTransitions>
<TransitionCollection>
<ContentThemeTransition />
<ReorderThemeTransition />
<EntranceThemeTransition IsStaggeringEnabled="False" />
</TransitionCollection>
</TreeViewList.ItemContainerTransitions>
</TreeViewList>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Add extended Scroller to extended spark List in Flex

I'm trying to add a custom Scroller.as (extended from spark.components.Scroller) to a InfiniteScrollList.as (extended from spark.components.list)
I wrote the following MXML code:
<list:InfiniteScrollList width="100%" height="100%" id="EventsList" useVirtualLayout="true">
<list:scroller>
<list:Scroller/> <!-- The Scroller.as Class -->
</list:scroller>
</list:InfiniteScrollList>
The List behavior works well but the extended Scroller component does not function at all.
What is the correct way to add this scroller functionality (in MXML or ActionScript) to the list?
The s:Scroller is used by wrapping it around the content or DataGroup. But the List class wraps all that functionality inside of it's skin, so I believe that in order to create a custom Scroller for a List, you actually need to do within the SkinClass.
<list:InfiniteScrollList width="100%" height="100%" id="EventsList"
useVirtualLayout="true" skinClass="MyListSkin" />
MyListSkin.mxml:
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009" minWidth="112">
<fx:Metadata>
[HostComponent("spark.components.Scroller")]
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<!-- The Scroller.as Class -->
<list:Scroller left="0" top="0" right="0" bottom="0" id="scroller" hasFocusableChildren="false">
<!--- #copy spark.components.SkinnableDataContainer#dataGroup -->
<s:DataGroup id="dataGroup" itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<!--- The default layout is vertical and measures at least for 5 rows.
When switching to a different layout, HorizontalLayout for example,
make sure to adjust the minWidth, minHeight sizes of the skin -->
<s:VerticalLayout gap="0" horizontalAlign="contentJustify" requestedMinRowCount="5" />
</s:layout>
</s:DataGroup>
</list:Scroller/>
</s:SparkSkin>

Windows Phone 8 equivalent to Androids alert dialog?

In an Android project I have this kind of alert dialog:
I want to replicate this in Windows Phone 8, however I haven't been able to find a suitable plugin/widget to do so. The list itself is populated by SharedPreferences.
My plan for Windows 8 was to use Isolated Storage Files to grab the required entries, is this the best way?
<clippy>It looks like you want to display a list to the user and allow them to pick an option </clippy>
If that is the case then you can use the ListPicker from the WP Toolkit. Install the nuget pack and use as such:
<toolkit:ListPicker FullModeHeader="CHOOSE LOCATION" ItemsSource="{Binding Cities}">
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Margin="0,20" TextWrapping="Wrap"
Style="{StaticResource PhoneTextExtraLargeStyle}">
<Run Text="{Binding Description}" />
<Run Text="-" />
<Run Text="{Binding Quality}" />
</TextBlock >
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>

How can a Caliburn.Micro sub menuitem click call an action on the containing view's viewmodel?

I have a top level menu in my ShellView and when selecting a sub MenuItem, I would like to call the following method on the ShellViewModel (a Conductor.Collection.AllActive).
public void SelectServer(string pServerName)
{
mDefaultClaimServer = pServerName;
}
The following does not work as no method gets called (I have tried various signatures and action parameters) -
<Menu Name="menu1" DockPanel.Dock="Top">
<MenuItem Header="Select Server" Name="ClaimServers">
<MenuItem.ItemTemplate>
<DataTemplate>
<!-- we need this else we show the class name -->
<TextBlock Text="{Binding DisplayName}">
<ContentControl cal:Message.Attach="[Event Click] = [Action TxTester.ShellViewModel.SelectServer($Text)]"/>
</TextBlock>
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
</Menu>
The following does call the ShellViewModel SelectServer method but I get null for the text of the clicked sub MenuItem (I also tried many other signatures and action parameters) -
<Menu Name="menu1" DockPanel.Dock="Top">
<MenuItem Header="Select Server" Name="ClaimServers" cal:Message.Attach="SelectServer($this.Text)">
<MenuItem.ItemTemplate>
<DataTemplate>
<!-- we need this else we show the class name -->
<TextBlock Text="{Binding DisplayName}" />
</DataTemplate>
</MenuItem.ItemTemplate>
</MenuItem>
</Menu>
I've been struggling with this a long time and can't figure it out. Can someone suggest the proper combination where I can pass the header text of a sub MenuItem to the ShellViewModel SelectServer method?
I got what I was trying to do working, per a post from Rob Eisenberg describing a "special trick to get the text from bound submenus" here - http://caliburnmicro.codeplex.com/discussions/287228
I would still love to know how to do what I was trying to do with standard OOTB logic if anyone has suggestions, so that I am able to understand CM better.
Basically I added this to the bootstrapper Configure() overide -
MessageBinder.SpecialValues.Add("$originalsourcecontext", context =>
{
var args = context.EventArgs as RoutedEventArgs;
if (args == null)
return null;
var fe = args.OriginalSource as FrameworkElement;
if (fe == null)
return null;
return fe.DataContext;
});
and added this to the xaml -
<MenuItem Header="_Select Server" Name="ClaimServers" cal:Message.Attach="SelectServer($originalsourcecontext)" />
and then I was passed the header text of the sub menuitem which is what I wanted.