How to bind by element name when control is inside a UserControl? - xaml

I am trying to bind the Fill property of a Rectangle to a property in the page's DataContext by using the element name, but because the Rectangle is in a UserControl the page is not found so binding does not occur.
Simplified example:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Converters_Theme="using:ProjectName.Common.Converters"
xmlns:CustomControls="using:ProjectName.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ProjectName.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="using:ProjectName.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ProjectName.Views.TestPage"
x:Name="pageName"
mc:Ignorable="d">
<Page.Resources>
<Converters_Theme:ThemeColorToSolidColorBrushConverter x:Key="ThemeColorToSolidColorBrushConverter"/>
<DataTemplate x:Key="ItemDataTemplate">
<StackPanel Orientation="Vertical">
<!-- ... -->
<Rectangle Fill="{Binding DataContext.Theme.Color, Converter={StaticResource ThemeColorToSolidColorBrushConverter}, ElementName=pageName}" MinHeight="40" MinWidth="40" />
<!-- ... -->
</StackPanel>
</DataTemplate>
</Page.Resources>
<Page.DataContext>
<ViewModel:PageViewModel />
</Page.DataContext>
<Grid>
<CustomControls:Tab>
<CustomControls:Tab.LeftContent>
<ItemsControl ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemDataTemplate}" />
</CustomControls:Tab.LeftContent>
<CustomControls:Tab.RightContent>
<!-- ... -->
</CustomControls:Tab.RightContent>
</CustomControls:Tab>
</Grid>
</Page>

Simple way to accomplish it is to make your ViewModel a StaticResource, e.g. in App.xaml (may work in your Page.xaml):
<App.Resources>
<ViewModel:PageViewModel x:Key="MyPageViewModel" />
</App.Resources>
And then reference to it in your Page.xaml:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Converters_Theme="using:ProjectName.Common.Converters"
xmlns:CustomControls="using:ProjectName.CustomControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:ProjectName.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="using:ProjectName.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ProjectName.Views.TestPage"
x:Name="pageName"
DataContext="{StaticResource MyPageViewModel}"
mc:Ignorable="d">
<Page.Resources>
<Converters_Theme:ThemeColorToSolidColorBrushConverter x:Key="ThemeColorToSolidColorBrushConverter"/>
<DataTemplate x:Key="ItemDataTemplate">
<StackPanel Orientation="Vertical">
<!-- ... -->
<Rectangle Fill="{Binding Theme.Color, Source={StaticResource MyPageViewModel}, Converter={StaticResource ThemeColorToSolidColorBrushConverter}}" MinHeight="40" MinWidth="40" />
<!-- ... -->
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid>
<CustomControls:Tab>
<CustomControls:Tab.LeftContent>
<ItemsControl ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemDataTemplate}" />
</CustomControls:Tab.LeftContent>
<CustomControls:Tab.RightContent>
<!-- ... -->
</CustomControls:Tab.RightContent>
</CustomControls:Tab>
</Grid>
</Page>
To do it in much more cleaner way, I advise you to use ViewModelLocator as a static resource in app, which will properties to all ViewModels and make it StaticResource in App.xaml. It is much more cleaner way to instantiate one class in App.xaml than every ViewModel you have.

Related

Hub Page Header Template doesn't work as expected

I'm porting over some Win RT code to UWP. One of the pages that doesn't work as expected is the HubPage.
I have a button in the HubSection HeaderTemplate which should be replacing the "see more" HyperLink. My button in my template appears but doesn't accept clicks.
The documentation states that I should be able to replace the "see more" hyperlink with my own template, I believe this is what my code is doing but doesn't work.
I'm unsure what value IsHeaderInteractive should be if I've attempting to replace the HubSection HeaderTemplate. Any help apprecaited
<Page
x:Class="Hub_Page.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Hub_Page"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<Style TargetType="HubSection">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Button Content="This doesn't click!"
Background="DarkCyan" Tapped="UIElement_OnTapped"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="outerGrid">
<Grid x:Name="innerGrid"
VerticalAlignment="Top">
<Hub x:Name="hub" SectionHeaderClick="Hub_OnSectionHeaderClick" >
<Hub.Header>
<!-- Back button and page title -->
<Grid>
<StackPanel Margin="13,0,20,0" Orientation="Horizontal">
<Button x:Name="backButton" Margin="0,0,20,0"/>
<TextBlock Text="x Manage Playlists" Margin="0,0,10,5" HorizontalAlignment="Left"/>
<Button Content="This does click"
Background="DarkGray" Tapped="UIElement_OnTapped"/>
</StackPanel>
</Grid>
</Hub.Header>
<!-- Playlists section -->
<HubSection Header="x Playlists" IsHeaderInteractive="True" >
<DataTemplate>
<ListView x:Name="playlistListView"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<!-- A playlist -->
<Grid HorizontalAlignment="Stretch">
<StackPanel Margin="10" Orientation="Vertical" HorizontalAlignment="Stretch" MaxWidth="500">
<TextBlock Text="{Binding Name}" TextTrimming="WordEllipsis" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
</Grid>
</Grid>
</Page>
It's by design. You could make your own HubSection's button by yourself. For example like the following:
<HubSection>
<DataTemplate>
<StackPanel>
<Button Content="Header" Click="Button_Click" Margin="0 0 0 10"></Button>
<TextBlock Text="here is content."></TextBlock>
</StackPanel>
</DataTemplate>
</HubSection>

MahApps Metro NumericUpDown problems

After using MahApp Metro formy project in WPF I encountered a problem I can't solve. the framework works fine except when I am using the NumericUpDown control.
I can see this control onto my UserControl while I'am working on it. But at the compilation the code then becomes :
The tag 'NumericUpDown' does not exist in XML namespace "http://metro.mahapps.com/winfx/xaml/controls". Line 75 Position 26.
With my XAML code it could perhaps help :
<UserControl x:Class="FullTest.Tabs.DataGridStrategie" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:convertors="clr-namespace:FullTest.ModelView.Convertors"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:utils="clr-namespace:FullTest.UtilityClasses"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
<ObjectDataProvider MethodName="GetType"
ObjectType="{x:Type sys:Type}" x:Key="colorsTypeOdp">
<ObjectDataProvider.MethodParameters>
<sys:String>System.Windows.Media.Colors, PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider ObjectInstance="{StaticResource colorsTypeOdp}" MethodName="GetProperties" x:Key="colorPropertiesOdp">
</ObjectDataProvider>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/emerald.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<DataGrid ItemsSource="{Binding Path=Str...}"
Grid.Row="0"
AutoGenerateColumns="False" Margin="0,0,-172,0" x:Name="MainGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Colors ..." Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="superCombo" ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}" SelectedItem="{Binding BrushColor, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="20" Height="20" Margin="5" Background="{Binding Name}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name of ..." x:Name="Str.." Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="itemNameTextBox" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Typ o....">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="TypeStrat" ItemsSource="{Binding Path=Typ....}" SelectedIndex="{Binding Index, UpdateSourceTrigger=PropertyChanged, Mode= TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--Here Appears the problem due to the controller-->
<DataGridTemplateColumn Header="">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:NumericUpDown Grid.Row="0"
Grid.Column="1"
Height="23"
Margin="5,5,5,5"
Interval="1"
StringFormat="{}{0:###0}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I could provide more information if it can be useful.

Binding ViewModel property to the primary View or sub view if primary view including sub view?

I have a primary View. It includes FirstSubView and SecondSubView.
<navigation:Page x:Class="Test.Views.PreimaryView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:localViews="clr-namespace:Test.Views"
mc:Ignorable="d"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
d:DesignWidth="1057" d:DesignHeight="707"
Title="TestView Page">
<UserControl.Resources>
<silverlightLib:BooleanVisibilityConverter x:Key="BooleanVisibilityConverter"></silverlightLib:BooleanVisibilityConverter>
</UserControl.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Background="Transparent">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<localViews:FirstSubView DataContext="{Binding VmFirst, Mode=TwoWay}"></localViews:FirstSubView>
<localViews:SecondSubView DataContext="{Binding VmSecond, Mode=TwoWay}" Visibility="{Binding IsAdjustVisible, Converter={StaticResource BooleanVisibilityConverter}}"></localViews:SecondSubView>
</StackPanel>
</StackPanel>
</ScrollViewer>
You see in the SecondSubView I have a binding property IsAdjustVisible.
My question is where an I set it? I set up it in both ViewModels to adjust the visibility of the second View. But it doesn't work, even when it is false, the View is still shown.
Finally I found the issue. I only need one place to put the properties. Which is the sub-View rather than the Main View.

VirtualizingStackPanel CanVerticallyScroll Property

I am playing with layout for Windows 8 Store Application and noticed that VirtualizingStackPanel.CanVerticallyScroll Property crash my application, but this property should work by this page.
It is strange, even Visual Studio Renders it correctly:
My code of XAML:
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="App5.GroupedItemsPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App5"
xmlns:data="using:App5.Data"
xmlns:common="using:App5.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Items}"
IsSourceGrouped="false"
ItemsPath="Items"
d:Source="{Binding Items, Source={d:DesignInstance Type=data:DataGroup, IsDesignTimeCreatable=True}}"/>
</Page.Resources>
<Grid Style="{StaticResource LayoutRootStyle}">
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" CanVerticallyScroll="False"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
</common:LayoutAwarePage>
What I want to achieve: Gridview does not have any groups and items stand in 2-3 rows with scroll to the right.
------------
|1|4|7|10|
------------
|2|5|8|11|
------------
|3|6|9|12|
------------

Add EventToCommand to each Row in xaml

Is there a way to add a DoubleClickEvent to each Row in xaml rather than using the event of the datagridcontrol?
Something like this (this code does not work):
<UserControl
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid" >
<xcdg:UserControl.Resources>
<Style TargetType="xcdg:DataRow">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand Command="{Binding SelectCommand, Mode=Default}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:DataGridControl}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Style>
</xcdg:UserControl.Resources>
...
Use a template instead of a style. (This assumes that the xceed datagrid's DataRow is templatable.)
<UserControl ...>
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate x:Key="DataTemplateKey">
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand Command="{Binding SelectCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<!-- put your row template here -->
</Grid>
<CheckBox Content="{Binding Path=ApplianceActionID, Converter={StaticResource LookupConverter}, ConverterParameter=ApplianceActionLookupValues}"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<!-- UI -->
</UserControl>