MahApps MetroProgressBar does not work inside ControlTemplate - c#

I would like to use MetroProgressBar in my UserControl.
<UserControl x:Class="WpfApplication7.UserControl1">
<StackPanel Background="#ccc">
<controls:MetroProgressBar IsIndeterminate="True"/>
</StackPanel>
</UserControl>
It works fine. But now I need to support external content in the user control.
So I created a new one "UserControl2" to demo:
<UserControl x:Class="WpfApplication7.UserControl2">
<UserControl.Resources>
<Style TargetType="{x:Type local:UserControl2}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:UserControl2}">
<StackPanel Background="#ccc">
<controls:MetroProgressBar IsIndeterminate="True"/>
<!--<ContentPresenter/>-->
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
</UserControl>
Then I put the both controls to the form:
<StackPanel>
<local:UserControl1 Background="#ccc"/>
<local:UserControl2 Background="#ccc" Margin="0,6,0,0"/>
</StackPanel>
As result I see that UserControl2 does not show Progress Bar.
How can I fix it?
Note: In the designer UserControl2 is rendered as expected with progress bar.

In your style for UserControl2, set properties EllipseDiameter and EllipseOffset to some value (default is 4), as shown below:
<Style TargetType="{x:Type local:UserControl2}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:UserControl2}">
<StackPanel Background="#ccc">
<controls:MetroProgressBar EllipseDiameter="12"
EllipseOffset="12"
IsIndeterminate="True"/>
<!--<ContentPresenter/>-->
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

Using {x: Bind} to bind to an XAML property, i.e. replacing {TemplateBinding XAMLProperty}

It is stated in MSDN that
Starting with Windows 10, version 1809, you can use the x:Bind markup extension anywhere you use TemplateBinding in a ControlTemplate.
However, when I try to replace TemplateBinding with {x:Bind} whilst defining the style of a custom control, as so,
<Style TargetType="local:PomodoroTimer" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:PomodoroTimer">
<Grid Width="300" Height="300" Background="{x:Bind Background}">
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I get the following error: Unable to resolve symbol 'Background'. What am I missing?
x:Bind needs code-behind. (see here)
So, thanks to MainWindow.xaml.cs, this works:
<Window
x:Class="Bindings.MainWindow"
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:local="using:Bindings"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<Style
x:Key="CustomButtonStyle"
TargetType="Button">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
BorderBrush="{x:Bind BorderBrush, Mode=OneWay}"
BorderThickness="{x:Bind BorderThickness, Mode=OneWay}">
<ContentControl Content="{x:Bind Content, Mode=OneWay}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Grid.Resources>
<Button
BorderBrush="SkyBlue"
BorderThickness="1"
Content="Custom Button"
Style="{StaticResource CustomButtonStyle}" />
</Grid>
</Window>
For custom (templated) controls, I'd go with:
Text="{TemplateBinding Text}"
or
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
for TwoWay bindings.
If you want to do x:Bind inside the ControlTemplate, this answer might help.

Force my tabitem to calcultate its width

I have the following style for my tabitems :
<Style x:Key="BoutonMenuHaut" TargetType="{x:Type TabItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Border Height="40" HorizontalAlignment="Stretch" CornerRadius="0" Name="border">
<Grid>
<ContentPresenterVerticalAlignment="Center"
HorizontalAlignment="Left"
TextBlock.Foreground="{StaticResource CouleurTexteBoutonsHaut}"
TextBlock.FontSize="{DynamicResource FontSizeBig}"
Name="textTab"
ContentSource="Header" Margin="10,0,60,0"
RecognizesAccessKey="True">
</ContentPresenter>
<Rectangle Height="2" x:Name="separation" Fill="Red" VerticalAlignment="Bottom" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
As you can see I bind the fontsize to a value defined like this :
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<sys:Double x:Key="FontSizeBig">16</sys:Double>
And in the window_sizechanged event I do this :
this.Resources["FontSizeBig"] = TextSizeFromResolution(12, height);
where height is the height of the screen.
But when I resize my window my tabitem doesn't resize itself and i'm not able to see all my tabs in the page anymore.
So my question is : How can I force the tabcontrol to resize the tabitems when the size changes ? (because the size of the text has changed so the tabitem's width should change too.
I've tried InvalidateMeasure, Update Layout... but I could not manage to make it work.
Could you help me ?
Thanks !
You could bind the width of the tabs to the ActualWidth of the tab control with a converter:
<Style TargetType="TabItem">
<Setter Property="Width" Value="{Binding
Path=ActualWidth, Converter={StaticResource YourConverter},
RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type TabControl}}}"/>
</Style>

How could i get control from ControlTemplate of ListBoxItem?

Good day.
For ItemContainerStyle of ListBox I set my own style:
StyleClass.xaml
<Style x:Key="ItemContainerGalleryStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid x:Name="itemGrid">
...
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListBoxGalleryStyle2" TargetType="{x:Type ListBox}">
<Setter Property="ItemContainerStyle" Value="{DynamicResource ItemContainerGalleryStyle}" />
</Style>
MainWindow.xaml
<Window ...>
<Window.Resources>
<XmlDataProvider x:Key="GalleryXmlDataProvider" Source="Gallery.xml"></XmlDataProvider>
</Window.Resources>
<Grid>
<ListBox x:Name="listBoxGallery"
Style="{StaticResource ListBoxGalleryStyle2}"
ItemsSource="{Binding Mode=Default,
Source={StaticResource GalleryXmlDataProvider},
XPath=/Gallery/Image}" />
</Grid>
</Window>
In code I want to retrieve Grid Control of my selected item. I attempt to do it by means of a listBoxGallery.Template.FindName. But I can't get at how to use this method.
How can I extract Grid from ControlTemplate?
You are trying to get an element from ListBoxItem's template and not from ListBox. So you need to get the exact ListBoxItem, before you using accessing its template. In below code snippet, I shown you how to get item from 0th element and taking the Grid from its template.
var container = listBoxGallery.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem;
var iremgrid = container.Template.FindName("itemGrid") as Grid;

WPF: PART_ContentHost not scrolling

I am trying to make a Log area within my application and the customer has requested the ability to cut/paste the log messages from this area.
I originally was using the following to setup the log area with scrolling, but this does not allow the user to select & copy text:
<ScrollViewer DataContext="{StaticResource Log}"
Content="{Binding Appender.Notification}"
Height="150">
<ScrollViewer.Resources>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
</Style>
</ScrollViewer.Resources>
</ScrollViewer>
I found this solution to create a read only TextBox with select-able text:
<TextBox Name="LoggingTextBox"
Height="250"
Width="950"
DataContext="{StaticResource Log}"
Text="{Binding Appender.Notification}"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border x:Name="PART_ContentHost" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
This works to allow the selection of text within the log area but the scrolling does not work. I added the properties for *ScrollBarVisibility (not in the original solution).
How can I get the scrolling to work using this TextBox styling?
The fix is pretty simple: just change your Border to a ScrollViewer, and you will get the standard scrolling behavior for a TextBox.

WPF content control styling

I have a custom control which is basically a contentcontrol
public class PromoAlarmBox : ContentControl
{
static PromoAlarmBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PromoAlarmBox), new FrameworkPropertyMetadata(typeof(PromoAlarmBox)));
}
}
I add it to the containing user control
<controls:PromoAlarmBox Grid.Row="9" Grid.Column="1" />
If I add the style to the containing usercontrols resources everything works fine
<UserControl.Resources>
<Style TargetType="{x:Type controls:PromoAlarmBox}">
<Setter Property="ContentControl.ContentTemplate">
<Setter.Value>
<DataTemplate >
<Rectangle Fill="Blue" Stroke="Black" Height="20" Width="20"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
But if I add it to generic.xaml in the custom controls project , nothing is show
<Style TargetType="{x:Type local:PromoAlarmBox}">
<Setter Property="ContentControl.ContentTemplate">
<Setter.Value>
<DataTemplate >
<Rectangle Fill="Blue" Stroke="Black" Height="20" Width="20"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
I know the style is applied as I have other controls in same project whos styles are defined in generic.xaml, Anyone have any ideas?
A simple static should do the trick...
static PromoAlarmBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(PromoAlarmBox), new FrameworkPropertyMetadata(typeof(PromoAlarmBox)));
}
Although im not sure why there is a difference when you use a style as a local resource and when you use generic , this works for me
<Style TargetType="{x:Type local:PromoAlarmBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Rectangle VerticalAlignment="Stretch" Fill="Yellow" Stroke="Black" Height="20" Width="20"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Categories

Resources