WPF Style with multiple contents - c#

I have created a style that creates a Label as a circle with the text in the middle.
<Style x:Key="RoundedLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Ellipse x:Name="cp" Margin="0,0,0,0" Fill="{TemplateBinding Background}" Height="{TemplateBinding Width}" Width="{TemplateBinding Width}" Stroke="Black" StrokeThickness="2" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Content>
<Border Padding="10">
<ContentPresenter Content="{TemplateBinding Content}"/>
</Border>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Its used in this way:
<Label Style="{StaticResource RoundedButtonStyle}" Content="{Binding CountValue}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" />
This works fine.
However I want to add further information to this label by having two text fields in different locations.
The first one already exists and displays in the centre of the ellipse.
Id like to add one which displays underneath the Ellipse.
Id like to be able to implement it in pure xaml if it is possible and use it something like this where the binding to SecondLabelText shows under the Ellipse:
<Label Style="{StaticResource RoundedButtonStyle}" Content="{Binding CountValue}" SecondContent="{Binding SecondLabelText}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" />
I can add the label into the style, but how do i set two separate contents?

Don't know if this is any use to you; went away and created this as a custom user control as a bit of a practice, You can create a new user control, setting 2 properties to receive the 2 contents:
using System.Windows;
using System.Windows.Controls;
namespace Custom_Control_Elipse_2_labels
{
/// <summary>
/// Interaction logic for EllipseWithTwoLabels.xaml
/// </summary>
public partial class EllipseWithTwoLabels : UserControl
{
public static readonly DependencyProperty Content1Property = DependencyProperty.Register("Content1", typeof(string), typeof(EllipseWithTwoLabels));
public static readonly DependencyProperty Content2Property = DependencyProperty.Register("Content2", typeof(string), typeof(EllipseWithTwoLabels));
public EllipseWithTwoLabels()
{
InitializeComponent();
DataContext = this;
}
public string Content1
{
get => (string) GetValue(Content1Property);
set => SetValue(Content1Property,value);
}
public string Content2
{
get => (string)GetValue(Content2Property);
set => SetValue(Content2Property, value);
}
}
}
The .xaml for the user control being
<Grid>
<Label Content="{Binding Content1}" Style="{StaticResource RoundedButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Red" BorderBrush="Red" BorderThickness="3" Height="100" Width="100" FontSize="20" FontWeight="Bold" ></Label>
<Label Content="{Binding Content2}" Margin="0,150,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" ></Label>
</Grid>
You can then just import it into any view to use it with: (
xmlns:local="clr-namespace:Custom_Control_Elipse_2_labels"
And use with the xaml:
<local:EllipseWithTwoLabels Height="300" Width="300" Content1="Content #1" Content2="Content #2"/>
Is one way to get it done :)
It provides something like this:

You can use for example Tag property of label to store extra data
<Label Style="{StaticResource RoundedLabelStyle}" Content="Content" Tag="Content#2"/>
In template just bind to Tag property
<ContentPresenter Content="{TemplateBinding Tag}"/>
Better approach is to use AttachedProperty. This allow you declare as many extra content as you want, without creating new type of control
public class LabelExtension
{
public static readonly DependencyProperty SecondContentProperty = DependencyProperty.RegisterAttached(
"SecondContent", typeof(object), typeof(LabelExtension));
public static void SetSecondContent(UIElement element, object value)
{
element.SetValue(SecondContentProperty, value);
}
public static object GetSecondContent(UIElement element)
{
return (object)element.GetValue(SecondContentProperty);
}
}
Set it on control
<Label Style="{StaticResource RoundedLabelStyle}" Content="Content" local:LabelExtension.SecondContent="Content#2"/>
Use from within template
<ContentPresenter Content="{TemplateBinding local:LabelExtension.SecondContent}"/>
Complete label style example
<Style x:Key="RoundedLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid Height="Auto" Width="Auto" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Ellipse x:Name="cp" Margin="0,0,0,0" Fill="{TemplateBinding Background}" Height="{TemplateBinding Width}" Width="{TemplateBinding Width}" Stroke="Black" StrokeThickness="2" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentPresenter.Content>
<Border Padding="10">
<StackPanel>
<ContentPresenter Content="{TemplateBinding Content}"/>
<ContentPresenter Content="{TemplateBinding Tag}"/>
<ContentPresenter Content="{TemplateBinding local:LabelExtension.SecondContent}"/>
</StackPanel>
</Border>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

Cant set 3 toggle button text content which use same style

i have three toggle buttons which use a singe style resource on wpf, now i cant set their content, content is declared more than once error, each toggle button has a different content.
Each toggle button uses an image as background also.
<UserControl.Resources>
<Style x:Key="Chromeless" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border BorderThickness="0" Width="197" Height="60">
<ContentPresenter TextElement.FontFamily="{TemplateBinding TextElement.FontFamily}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,0,0,0"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Image x:Key="page1Pressed" Source="/graph_engine;Component/cucaracha/LD3/button_1.png" Height="60" Width="197" />
<Image x:Key="page1" Source="/graph_engine;Component/cucaracha/LD3/button_1_pressed.png" Height="60" Width="197" />
<Image x:Key="page2Pressed" Source="/graph_engine;Component/cucaracha/LD3/button_2.png" Height="60" Width="197" />
<Image x:Key="page2" Source="/graph_engine;Component/cucaracha/LD3/button_2_pressed.png" Height="60" Width="197" />
<Image x:Key="page3Pressed" Source="/graph_engine;Component/cucaracha/LD3/button_3.png" Height="60" Width="197" />
<Image x:Key="page3" Source="/graph_engine;Component/cucaracha/LD3/button_3_pressed.png" Height="60" Width="197" />
</UserControl.Resources>
<Viewbox Stretch="Fill" StretchDirection="Both">
<Grid Height="60" Name="grid1" Width="591" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="197" />
<ColumnDefinition Width="197" />
<ColumnDefinition Width="197" />
</Grid.ColumnDefinitions>
<ToggleButton Style="{StaticResource Chromeless}" Name="page1" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Foreground="{x:Null}" Checked="page1_Checked" Unchecked="page1_Unchecked">
<DynamicResource ResourceKey="page1"/>
</ToggleButton>
<ToggleButton Grid.Column="1" Style="{StaticResource Chromeless}" Name="page2" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Foreground="{x:Null}" Unchecked="page2_Unchecked" Checked="page2_Checked">
<DynamicResource ResourceKey="page2"/>
</ToggleButton>
<ToggleButton Grid.Column="2" Style="{StaticResource Chromeless}" Name="page3" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" Foreground="{x:Null}" Checked="page3_Checked" Unchecked="page3_Unchecked">
<DynamicResource ResourceKey="page3"/>
</ToggleButton>
</Grid>
</Viewbox>
Do you mean you can't change the image when you pressed down the toggle button? You only set a image to the content of toggle button. You can use Visual State Manager to change the background like this
If you just want to set the image and failed. Please check the image path.

How to create a speech bubble in UWP?

I'm creating a chat application and would like to create the typical speech bubble that contains each message. I created a Path object in Blend (in XAML) like this:
The problem is that the path is has designed to have a specified width and height and I would like it to wrap around the text without stretching, so it won't look deformed, like a border does.
How can I make it behave like I want?
You may use Polygon in combination with StackPanel:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Left"
Padding="6"
>
<Polygon Points="0,0 15,0 15,15"
Fill="LightGray"
Margin="0,10,0,0"
/>
<Border Background="LightGray"
CornerRadius="3"
Padding="6"
VerticalAlignment="Top"
>
<TextBlock Text="Text"
TextWrapping="WrapWholeWords"
Width="100"
Height="50"
/>
</Border>
</StackPanel>
which looks like this:
EDIT:
Version with border:
<Grid HorizontalAlignment="Left"
Padding="6"
>
<Polygon Points="0,0 15,0 15,15"
Fill="LightGray"
Stroke="Black"
Margin="0,10,0,0"
/>
<Border Background="LightGray"
BorderBrush="Black"
BorderThickness="0.5"
CornerRadius="3"
Padding="6"
Margin="14,0,0,0"
VerticalAlignment="Top"
>
<TextBlock Text="Text"
TextWrapping="WrapWholeWords"
Width="100"
Height="50"
/>
</Border>
<Polygon Points="0,0 15,0 15,15"
Fill="LightGray"
Margin="0,10,0,0"
/>
</Grid>
This is probably not the easiest and the best way how to do this, maybe Path will be better to do this, but it works:
Here is a Custom control that declares a Dependency Property for the Text and reuse some properties of the base control in its template (Background, Width, Heigth).
First the class definition: (SpeechBubbleControl.xaml.cs)
[TemplatePart(Name = PartBubbleText, Type = typeof(TextBlock))]
public sealed partial class SpeechBubbleControl : Control
{
private const string PartBubbleText = "BubbleText";
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(SpeechBubbleControl), new PropertyMetadata(""));
public SpeechBubbleControl()
{
DefaultStyleKey = typeof(SpeechBubbleControl);
}
public string Text
{
get { return GetValue(TextProperty).ToString(); }
set { SetValue(TextProperty, value); }
}
}
With its default template (SpeechBubbleControl.xaml):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
>
<Style TargetType="local:SpeechBubbleControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SpeechBubbleControl">
<Grid Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Fill="{TemplateBinding Background}" Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
<Path Fill="{TemplateBinding Background}" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="-15,-5,0,20" Width="30" Height="40" Data="M0,0 L15,40 30,20 0,0" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False">
<Path.RenderTransform>
<CompositeTransform Rotation="-20"/>
</Path.RenderTransform>
</Path>
<Rectangle Fill="{TemplateBinding Background}" RadiusX="10" RadiusY="10" Margin="1"/>
<TextBlock Name="BubbleText" HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{TemplateBinding Text}" FontSize="20" TextWrapping="Wrap"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
You have to import this resource into your application resource using something like this in your app.xaml:
<Application
x:Class="App6.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="SpeechBubbleControl.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And finally a sample test page, which use this control with bindings on width, height (based on the sliders) and the text that must be displayed.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBox x:Name="testText" Grid.ColumnSpan="2" PlaceholderText="My text..." />
<Slider x:Name="width" Grid.Row="1" Minimum="50" Maximum="500" Value="200" />
<Slider x:Name="height" Grid.Row="1" Grid.Column="2" Minimum="50" Maximum="500" Value="100" />
<local:SpeechBubbleControl Grid.Row="2" Grid.ColumnSpan="2"
Width="{Binding Value, ElementName=width}"
Height="{Binding Value, ElementName=height}"
Text="{Binding Text, ElementName=testText, FallbackValue=Hello}"
Background="Beige" >
</local:SpeechBubbleControl>
</Grid>
<local:SpeechBubbleControl Grid.Row="2" Grid.ColumnSpan="2"
Width="{Binding Value, ElementName=width}" Height="{Binding Value, ElementName=height}"
Text="{Binding Text, ElementName=testText, FallbackValue=Hello}"
Background="Beige" >
</local:SpeechBubbleControl>
</Grid>
Here is the result:
Note that my answer is adapted from this one: WPF speech bubble

Display Header on Textbox only if text is set in UWP XAML

I'm trying to modify the look & feel of the textbox control in a UWP App to what our designers drawn in sketch. That includes to have a header only shown when no text is set in the textbox.
I assume that I have to modify the visibility of the HeaderContentPresenter and its DataTemplate:
<ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource TextControlHeaderForeground}" FontWeight="Normal" Margin="0,0,0,2" Grid.Row="0" x:DeferLoadStrategy="Lazy" BorderThickness="0" Visibility="Collapsed" />
I wrote an IValueConvert to convert "empty string" to visibility, but I am stuck with the binding. I can't see any way to get the datacontext.
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" Foreground="{StaticResource DarkGrey}" FontSize="10" FontFamily="TheSansB4SemiLight" Visibility="{Binding Converter={StaticResource EmptyStringToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
How can I access the text written on the textbox within the DataTemplate?
Thanks
Update with Code
I want this
MainPage.xaml
Three Textboxes I applied the same style to.
<TextBox Header="Username" PlaceholderText="Username" Grid.Column="1" HorizontalAlignment="Left" Height="67" Margin="20,143,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="295" Style="{StaticResource InputField}" />
<TextBox Header="Surname" PlaceholderText="Surname" Grid.Column="1" HorizontalAlignment="Left" Height="67" Margin="20,249,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="295" Style="{StaticResource InputField}"/>
<TextBox Header="Name" PlaceholderText="Name" Grid.Column="1" HorizontalAlignment="Left" Height="67" Margin="20,196,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="295" Style="{StaticResource InputField}"/>
Styles.xaml
Basic shareable styles within a ResourceDict, refrenced in App.xaml. When I name the textboxes "InputField", the mechanism starts working, but obviously I have name conflicts and strange behavior.
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock
Foreground="{StaticResource DarkGrey}"
FontSize="10"
FontFamily="TheSansB4SemiLight"
Visibility="{Binding Text, Converter={StaticResource EmptyStringToVisibilityConverter}, ElementName=InputField}"
Text="{Binding Header, ElementName=InputField}"
/>
</DataTemplate>
</Setter.Value>
</Setter>
Question
What element within the Template must be named to be accessible through binding? I assume it's one of the elements the textbox control is made of, but I can't find out how.
<Grid><Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1" CornerRadius="5"/>
<ContentControl x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" Foreground="{ThemeResource TextControlPlaceholderForeground}" IsHitTestVisible="False" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1"/>
<Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="2" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" VerticalAlignment="Stretch" Visibility="Collapsed"/>
<ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource TextControlHeaderForeground}" FontWeight="Normal" Margin="0,0,0,2" Grid.Row="0" x:DeferLoadStrategy="Lazy" BorderThickness="0" Visibility="Collapsed" />
<ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled" Grid.ColumnSpan="2"/>
</Grid>
There are 2 solutions here.
Hide/Show TextBox Header based on Converter and TextBox.Text Length
Hide/Show TextBox Header based on CustomControl and Lost/Gain Focus
1) Hide/Show TextBox Header based on Converter and TextBox.Text Length
You need to Name your TextBox inside DataTemplate so that binding can find the item and Process the value.
Below is a sample of Converter.
public class DataToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
Visibility dataVisible = (value.ToString().Length == 0) ? Visibility.Visible : Visibility.Collapsed;
return dataVisible;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
And below is how I use it in a DataTemplate inside ListView.
<ListView ItemsSource="{Binding }">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100" TextWrapping="Wrap" >
<TextBox.Header>
<TextBlock Text="Header String" Visibility="{Binding Text, Converter={StaticResource DataToVisibilityConverter}, ElementName=textBox}"/>
</TextBox.Header>
</TextBox>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Final Result
Edit
After you updated your question things got more simpler.
2. Hide/Show TextBox Header based on CustomControl and Lost/Gain Focus
You need to create a custom control to handle events that are common across for your textblock.
So as per your image, When you get focus, you show Header and lose focus, you hide it since there is text in placeholder.
Below is a custom control that does exactly that.
public sealed class MyTextBox : TextBox
{
public MyTextBox()
{
this.DefaultStyleKey = typeof(TextBox);
this.GotFocus += MyTextBox_GotFocus;
this.LostFocus += MyTextBox_LostFocus;
}
private void MyTextBox_LostFocus(object sender, RoutedEventArgs e)
{
this.Header = "";
}
private void MyTextBox_GotFocus(object sender, RoutedEventArgs e)
{
this.Header = this.PlaceholderText;
}
}
And the usage will be
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<local:MyTextBox PlaceholderText="User Name" x:Name="txtUserName" Grid.Row="0" Margin="10"/>
<local:MyTextBox PlaceholderText="Email" x:Name="txtEmail" Grid.Row="1" Margin="10"/>
<local:MyTextBox PlaceholderText="Password" x:Name="txtPassword" Grid.Row="2" Margin="10"/>
</Grid>

WPF DataGrid Dock panel grouping

I'm using wpf datagrid, and I'm using grouping to group my orders by number of order, and I also have a status for each order item, like : is it proceed or not, but somehow it looks messy on screen if I list each status for each item, because if one item of each order is proceed that means all of items are also proceed, so I'm wondering is it possible to move status next to Order number (Expander header - DockPanel) so I might get look like this:
Order number :# 1 - Order is in progress.
Order number :# 2 - Order is in progress.
Order number :# 3 - Order is not in progress.
So question is:
IS IT POSSIBLE TO MOVE 'ORDER STATUS' NEXT TO Order Number part?:)
Here is my code:
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" Content="Finish order" Margin="0,0,55,5" DockPanel.Dock="Right" Click="btnFinishOrder_Click" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="btnTakeIt_Click" Content="Take it!" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
code behind:
public partial class MainWindow : Window
{
CollectionViewSource collectionViewSource = new CollectionViewSource();
public MainWindow()
{
try
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = ordersList;
collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = collectionViewSource;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1000);
timer.Tick += timer_Tick;
timer.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
The Expander.Header does not get one of your view models as DataContext. Instead the header gets an object that inherits from CollectionViewGroup. One of its properties is Name. That's why you can bind to Name in your XAML
<TextBlock ... Text="{Binding Path=Name,StringFormat= Order Number:# {0}}" />
Another property of interest is Items. That's the list of all view models of that group. Now it's easy to access an item's property in the header
<TextBlock ... Text="{Binding Path=Items[0].MyProperty}" />

Windows Phone Equivalent of a WinRT ContentControl

I am trying to port a custom content control class from a WinRT app to a Windows Phone 8 app, but I cannot figure out exactly how to accomplish it. I essentially want to port something like the following:
MenuPanel.cs
public sealed class MenuPanel : ContentControl
{
#region ContentVisibility
/// <summary>
/// ContentVisibility Dependency Property
/// </summary>
public static readonly DependencyProperty ContentVisibilityProperty =
DependencyProperty.Register(
"ContentVisibility",
typeof(Visibility),
typeof(MenuPanel),
new PropertyMetadata(Visibility.Visible, null));
/// <summary>
/// Gets or sets the ContentVisibility property
/// </summary>
public Visibility ContentVisibility
{
get { return (Visibility)GetValue(ContentVisibilityProperty); }
set { SetValue(ContentVisibilityProperty, value); }
}
#endregion
... Lots more, but truncated for brevity
}
Generics.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Expansion.WinRT.Controls">
<Style TargetType="local:MenuPanel">
<Setter Property="ContentVisibility" Value="Visible" />
<Setter Property="EnableVisibility" Value="Collapsed" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MenuPanel">
<Grid>
<Border BorderBrush="#33FFFFFF" BorderThickness="16" CornerRadius="1" />
<Border BorderBrush="#4CFFFFFF" BorderThickness="8" CornerRadius="1" Margin="4" />
<Border BorderBrush="White" Background="#26FFFFFF" BorderThickness="2" CornerRadius="1" Margin="7" Padding="3">
<StackPanel>
<ContentPresenter
Visibility="{TemplateBinding ContentVisibility}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}" />
<Button
Name="EnableButton"
Visibility="{TemplateBinding EnableVisibility}"
BorderBrush="Transparent"
Content="+"
FontSize="40"
Padding="0,-10,0,0"
HorizontalAlignment="Center"
Width="70" />
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainPage.xaml
...
<local:MenuPanel Name="MainMenuPanel" Width="520" VerticalAlignment="Center">
<StackPanel>
<StackPanel Name="StartMenu" Visibility="Visible">
<Button Name="NewGameButton" Content="New Game" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Transparent" FontSize="30" />
<Button Name="LoadGameButton" Content="Load Game" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Transparent" FontSize="30" />
<Button Name="OptionsButton" Content="Options" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Transparent" FontSize="30" />
</StackPanel>
</StackPanel>
</local:MenuPanel>
...
I took a look at http://msdn.microsoft.com/en-us/library/windowsphone/develop/system.windows.controls.contentcontrol(v=vs.105).aspx but it didn't help much.

Categories