In UWP I'm trying to create a SplitView on the left side of the screen with four buttons, any of the first three buttons open the pane but show different content according to which button was clicked: 1st = preferences, 2nd = account, 3rd = info about program. The 4th button simply closes the pane back to its original state. My question is how do I go about showing different content in the pane according to the button clicked? Is there maybe a better control for this?
Content when the first button is clicked
Content when the second button is clicked
Content when the third button is clicked
Right now each content simply has a different header but I plan to add things like a theme changer in the preferences content, account information in the user content and info related to the program in the info content.
XAML Code:
<Grid>
<SplitView IsPaneOpen="False"
DisplayMode="CompactInline"
CompactPaneLength="50"
OpenPaneLength="250">
<SplitView.Pane>
<StackPanel Orientation="Horizontal">
<StackPanel x:Name="ButtonPanel"
Background="Goldenrod">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="FontSize"
Value="25">
</Setter>
<Setter Property="Width"
Value="50">
</Setter>
<Setter Property="Height"
Value="50">
</Setter>
<Setter Property="Foreground"
Value="Black">
</Setter>
<Setter Property="Background"
Value="Transparent">
</Setter>
</Style>
</StackPanel.Resources>
<Button x:Name="PreferencesButton"
Content="☰"
Click="PreferencesButton_Click">
</Button>
<Button x:Name="UserButton"
FontFamily="Segoe MDL2 Assets"
Content=""
Click="UserButton_Click">
</Button>
<Button x:Name="InfoButton"
Content="🛈"
Click="InfoButton_Click">
</Button>
<Button x:Name="CloseButton"
FontFamily="Segoe MDL2 Assets"
Content=""
Click="CloseButton_Click">
</Button>
</StackPanel>
<StackPanel x:Name="ContentPanel">
<!-- Add content based on which button was clicked -->
</StackPanel>
</StackPanel>
</SplitView.Pane>
<SplitView.Content>
<Grid>
<TextBlock Text="SplitView Basic"
FontSize="54"
Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center">
</TextBlock>
</Grid>
</SplitView.Content>
</SplitView>
</Grid>
Update:
You can create three UserControls to add different contents and add these UserControls in your ContentPanel. When you click the Button, show the corresponding content and hide other UserControls. You can use VisualStateManager or in code-behind to switch different contents. For example:
.xaml:
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Account">
<VisualState.Setters>
<Setter Target="Per.Visibility" Value="Collapsed"/>
<Setter Target="MyAccount.Visibility" Value="Visible"/>
<Setter Target="MyInformation.Visibility" Value="Collapsed"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Preferences">
<VisualState.Setters>
<Setter Target="Per.Visibility" Value="Visible"/>
<Setter Target="MyAccount.Visibility" Value="Collapsed"/>
<Setter Target="MyInformation.Visibility" Value="Collapsed"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Information">
<VisualState.Setters>
<Setter Target="Per.Visibility" Value="Collapsed"/>
<Setter Target="MyAccount.Visibility" Value="Collapsed"/>
<Setter Target="MyInformation.Visibility" Value="Visible"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<SplitView x:Name="MySplitView"
IsPaneOpen="False"
DisplayMode="CompactInline"
CompactPaneLength="50"
OpenPaneLength="250">
<SplitView.Pane>
<StackPanel Orientation="Horizontal">
......
<StackPanel x:Name="ContentPanel">
<!-- Add content based on which button was clicked -->
<local:PerUserControl x:Name="Per" Visibility="Collapsed"></local:PerUserControl>
<local:AccountUserControl x:Name="MyAccount" Visibility="Collapsed"></local:AccountUserControl>
<local:InfoUserControl x:Name="MyInformation" Visibility="Collapsed"></local:InfoUserControl>
</StackPanel>
</StackPanel>
</SplitView.Pane>
<SplitView.Content>
......
</SplitView.Content>
</SplitView>
</Grid>
.cs:
private void PreferencesButton_Click(object sender, RoutedEventArgs e)
{
MySplitView.IsPaneOpen = true;
VisualStateManager.GoToState(this, "Preferences", true);
// Or manually hide or show UserControls
//Per.Visibility = Visibility.Visible;
//MyAccount.Visibility = Visibility.Collapsed;
//MyInformation.Visibility = Visibility.Collapsed;
}
private void UserButton_Click(object sender, RoutedEventArgs e)
{
MySplitView.IsPaneOpen = true;
VisualStateManager.GoToState(this, "Account", true);
}
private void InfoButton_Click(object sender, RoutedEventArgs e)
{
MySplitView.IsPaneOpen = true;
VisualStateManager.GoToState(this, "Information", true);
}
Related
I am implementing a Flyout in a UWP app as you can see on the image below. I want the AutoSuggestBox in the Flyout to appear in (and fill) the PageHeader, but it appears below it.
This is my XAML:
<Button x:Name="searchButton" Margin="0" Padding="0" BorderThickness="0" RelativePanel.AlignBottomWith="pageHeader">
<Button.Content>
<FontIcon Height="48" Width="48" Glyph=""/>
</Button.Content>
<Button.Flyout>
<Flyout>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
<Setter Property="Height" Value="40"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel Margin="0" VerticalAlignment="Top">
<AutoSuggestBox x:Name="innerSearchBox" PlaceholderText="Search" VerticalAlignment="Top"/>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
How can I make the AutoSugesstBox appear in and fill the PageHeader?
Set Placement as Left for Flyout.
<Flyout Placement="Left">
If you want to make the AutoSuggestBox to cover the entire width of the application, set the width of the AutoSuggestBox to ApplicationView width.
You can do this by
public MainPage()
{
this.InitializeComponent();
ApplicationView.GetForCurrentView().VisibleBoundsChanged += MainPage_VisibleBoundsChanged;
var bound = ApplicationView.GetForCurrentView().VisibleBounds;
innerSearchBox.Width = (int)bound.Width - 48; //48 is the size of the button
}
private void MainPage_VisibleBoundsChanged(ApplicationView sender, object args)
{
var bound = ApplicationView.GetForCurrentView().VisibleBounds;
innerSearchBox.Width = (int)bound.Width - 48;
}
Basically I need to customize the pivot control on my uwp app and I use the style of pivot from windows phone 8.1. And it looks like this eventually(the yellow part is the content of the pivot item, I just use color to differentiate the header and the content)
But right now it does not meet the require of the original design. So I have two questions here:
1.How do I limit user flick the pivot in one direction? For example, users could only flick the control from left to right because the yellow content part will move to left and cover the header if the pivot is flicked from the right to the left. The content, which is the yellow part, will move entirely along with your finger and the other covered pivot header will be shown because the yellow part moves away, as you can see on the image. This is the reason why I care about the swiping direction because if you swipe left, the yellow part will covers part of the header before the gesture is done(which is not showing up in the image).
2.How to change the foreground color of the unselected pivotitem header? Right now as you can see, during the flicking process, the yellow content part will move away and the unselected header will be shown. That looks weird and it is not a good design at all. The unselected header is suppose to be transparent or be the same as the background color of the page.
Here is the code of the style:
<Style x:Key="PivotStyle1" TargetType="Pivot">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Foreground" Value="{ThemeResource PivotForegroundThemeBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Pivot">
<Grid x:Name="RootElement" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Orientation">
<VisualState x:Name="Portrait">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="TitleContentControl">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PivotPortraitThemePadding}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Landscape">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Margin" Storyboard.TargetName="TitleContentControl">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource PivotLandscapeThemePadding}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="TitleContentControl" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" Style="{StaticResource PivotTitleContentControlStyle}"/>
<ScrollViewer x:Name="ScrollViewer" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="Hidden" Margin="{TemplateBinding Padding}" Grid.Row="1" Template="{StaticResource ScrollViewerScrollBarlessTemplate}" VerticalSnapPointsType="None" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalContentAlignment="Stretch" ZoomMode="Disabled">
<PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
<PivotHeaderPanel x:Name="Header">
<PivotHeaderPanel.RenderTransform>
<CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0"/>
</PivotHeaderPanel.RenderTransform>
</PivotHeaderPanel>
<ItemsPresenter x:Name="PivotItemPresenter">
<ItemsPresenter.RenderTransform>
<TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0"/>
</ItemsPresenter.RenderTransform>
</ItemsPresenter>
</PivotPanel>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And the XAML code for the pivot control:
<Pivot Style="{StaticResource PivotStyle1}">
<Pivot.HeaderTemplate>
<DataTemplate>
<Grid Height="auto">
<Grid.RowDefinitions>
<RowDefinition Height="21*"/>
<RowDefinition Height="299*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="19*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding}"
Margin="14,50,9,-120"
Grid.Row="1"
HorizontalAlignment="Center"
FontSize="48"
FontFamily="ms-appx:NotoSansCJKsc-Black.otf#Noto Sans CJK SC"
TextWrapping="Wrap"
LineStackingStrategy="BlockLineHeight"
LineHeight="49" Width="48"
Height="auto"/>
</Grid>
</DataTemplate>
</Pivot.HeaderTemplate>
<PivotItem Header="评论" Margin="83,-47,0,0" Background="Yellow">
<Grid>
<ListView x:Name="listview" d:LayoutOverrides="TopPosition, BottomPosition" ItemTemplate="{StaticResource GroupTemplate}" ItemsSource="{Binding Groups}" Margin="10,0,0,0"/>
</Grid>
</PivotItem>
<PivotItem Header="转发" Margin="93,-47,0,0" Background="Yellow">
<Grid>
<ListView x:Name="listview2" d:LayoutOverrides="TopPosition, BottomPosition" ItemTemplate="{StaticResource GroupTemplate}" ItemsSource="{Binding Groups}"/>
</Grid>
</PivotItem>
</Pivot>
For your first question, you have customize the style of the Pivot control, your gesture shown above works fine on the mobile emulator, but not on the local machine. This is the problem about ManipulationMode in the design of a Pivot control. Pivot control's Gesture is achieved inside it's style, so it is possible to manipulate it in one direction, but we need to find the key point in the style.
You can use Manipulation to do this. You can modify your style of Pivot control like this:
<PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
<PivotHeaderPanel x:Name="Header" ManipulationMode="None">
<PivotHeaderPanel.RenderTransform>
<CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0" />
</PivotHeaderPanel.RenderTransform>
</PivotHeaderPanel>
<ItemsPresenter x:Name="PivotItemPresenter" ManipulationMode="None">
<ItemsPresenter.RenderTransform>
<TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0" />
</ItemsPresenter.RenderTransform>
</ItemsPresenter>
</PivotPanel>
and use this Pivot control like this:
<Pivot Style="{StaticResource PivotStyle1}" x:Name="myPivot" ManipulationMode="TranslateX" ManipulationStarting="OnStarting" ManipulationCompleted="OnCompleted">
...
</Pivot>
And the code behind:
public double pointx1;
private void OnCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
var pointx2 = Window.Current.CoreWindow.PointerPosition.X;
if (pointx2 > pointx1)
{
if (myPivot.SelectedIndex == 0)
myPivot.SelectedIndex = 1;
else
myPivot.SelectedIndex = 0;
}
else
return;
}
private void OnStarting(object sender, ManipulationStartingRoutedEventArgs e)
{
pointx1 = Window.Current.CoreWindow.PointerPosition.X;
}
Here is also a workaround method to solve this problem, consider that there is no manipulation in the style of Pivot, you can achieve this using PointerPoint you can modify your style of Pivot control like this:
<PivotPanel x:Name="Panel" VerticalAlignment="Stretch" ManipulationMode="None">
<PivotHeaderPanel x:Name="Header">
<PivotHeaderPanel.RenderTransform>
<CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0" />
</PivotHeaderPanel.RenderTransform>
</PivotHeaderPanel>
<ItemsPresenter x:Name="PivotItemPresenter">
<ItemsPresenter.RenderTransform>
<TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0" />
</ItemsPresenter.RenderTransform>
</ItemsPresenter>
</PivotPanel>
and use this Pivot control like this:
<Pivot Style="{StaticResource PivotStyle1}" PointerReleased="OnPointerExited" PointerPressed="OnPointerPressed" x:Name="myPivot">
...
</Pivot>
And the code behind:
public PointerPoint pointer1;
private void OnPointerExited(object sender, PointerRoutedEventArgs e)
{
var pointer2 = e.GetCurrentPoint(myPivot);
var position1x = pointer1.Position.X;
var position2x = pointer2.Position.X;
if (position2x > position1x)
{
if (myPivot.SelectedIndex == 0)
myPivot.SelectedIndex = 1;
else
myPivot.SelectedIndex = 0;
}
else
return;
}
private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
{
pointer1 = e.GetCurrentPoint(myPivot);
}
And for your second question, as #ganchito55 said, you can modify the style of PivotHeaderItem.
Update:
If you just don't want to see the header of the other item when you manipulate it, you can modify the PivotHeaderItem like this:
......
<Setter Property="FontWeight" Value="{ThemeResource PivotHeaderItemThemeFontWeight}" />
<Setter Property="CharacterSpacing" Value="{ThemeResource PivotHeaderItemCharacterSpacing}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="Padding" Value="{ThemeResource PivotHeaderItemMargin}" />
<Setter Property="Height" Value="48" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="IsTabStop" Value="False" />
......
I have a xaml page with Gridview which has a Button.I am using a grouped Item page. The buttons are generated based on the dataset returned.
10 records will display 10 buttons.
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="Auto" Height="Auto" >
<Button Click="ItemView_ItemClick">
<StackPanel Margin="5" >
<TextBlock Tag="cntCustName" Style="{ThemeResource CntNormalTextBlockStyle}" Text="{Binding CUSTOMERNAME }"/>
<TextBlock Tag="cntCatCode" Style="{ThemeResource CntLrgTextBlockStyle}" Text="{Binding CATEGORYCODE}"/>
<TextBlock Tag="cntDay" Style="{ThemeResource CntNormalTextBlockStyle}" Text="{Binding DAY}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
I am getting data in a foreach loop. I want to be able to assign the styles of the buttons
dynamically based on some criteria which I have.
foreach (ContactData ContactData in _openContatcs)
{
if (ContactData.CFLAG)
{
//this is an example
Application.Current.Resources["contactSquare"] = ampStyle;
}
group.Items.Add(ContactData);
}
Styles are defined like this in a folder: Assests/Resources/BaseAPStyles.xaml
<Style x:Name="contactSquare" TargetType="Button">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Height" Value="160"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Width" Value="160"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="#ffffc600">
<ContentPresenter>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My buttons are not showing the styles. How can I achieve this?
use x:key="contactSqaure" to find the style in the application resources.
Then, access the button you would like to style and assign the style to the button like this.
yourButton.Style = Application.Resources.Current["contactSqaure"] as Style;
You can also define styles in C#, or edit the button's dependency properties.
yourButton.Height = 160;
yourButton.VerticalAlignment = VerticalAlignment.Center;
you can access the button in your datatemplate when it loads.
<DataTemplate>
<Button Loaded="Button_Loaded" .../>
....
void Button_Loaded(object sender, RoutedEventArgs args)
{
(sender as Button).Style = yourStyle;
}
I'm using multiple images to create something like a virtual keyboard. I wish to add a short period of time after a image is clicked, where at the short period of time, all clicks on images are disabled. Does any1 knows how to do it? Here's my code for one of the images.
<Button Grid.Column="2" Command="{Binding Path=PressAndRelease}" CommandParameter="Q" Style="{StaticResource TransparentButton}" Effect="{Binding}">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image Name="imgNormalQ" Source="/wa;com/Images/alp/q.png" Height="127"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Panel.ZIndex" Value="999"/>
<Setter TargetName="imgPressedQ" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
in Silverlight I have done this using VisualStateManager
there is not much difference in WPF
edited
I have created sample Storyboard to disabled WPF UIElement.
<StackPanel>
<Border x:Name="MainContent">
<StackPanel x:Name="ButtonPanel">
<Button Width="100" Click="AnyButton_Click">Busy State 1</Button>
<Button Width="100" Click="AnyButton_Click">Busy State 2</Button>
<Button Width="100" Click="AnyButton_Click">Busy State 3</Button>
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="BusyStates">
<VisualState x:Name="Ready" />
<VisualState x:Name="Busy">
<Storyboard>
<BooleanAnimationUsingKeyFrames Duration="0"
Storyboard.TargetName="ButtonPanel"
Storyboard.TargetProperty="IsEnabled">
<DiscreteBooleanKeyFrame KeyTime="0" Value="False"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
<Button Width="100" x:Name="ClearButton" Click="ClearButton_Click">Ready</Button>
</StackPanel>
the VisualState named "Busy" will animate ButtonPanel.IsEnabled = false (at keytime=0)
here's basic code behind
private void AnyButton_Click(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToElementState(MainContent, "Busy", true);
}
private void ClearButton_Click(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToElementState(MainContent, "Ready", true);
}
PS. if you follow the MVVM. VisualStateManager responsible for View. it should be part of XAML not ViewModel
EDIT: Original title: When I add a custom control based on a timer, my templates are ignored.
I'm working on the 70-511 training kit from Microsoft Press, and combined two practice exercises together from chapter 5.
The problem is that when I add the custom control to my MainWindow, it runs, but the triggers on the Button template are ignored. When the same control is removed, the triggers are honored.
For those who don't have access to the book, and don't feel like analyzing the code, it's a custom control with a label that has a dependency property setup to update on a timer object (once per second) with the current system time.
As you might infer from my attached code, the custom control is in a separate assembly referenced by the 5_3 project.
I'm a bit stumped on this one. What is causing this?
Here is the code:
MainWindow.xaml:
<Window x:Class="chapter5_3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:chapter5_3CustomControl;assembly=chapter5_4CustomControl">
<Window.Resources>
<ControlTemplate TargetType="{x:Type Button}" x:Key="ButtonTemplate">
<Border Name="Bord1" BorderBrush="Olive" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Rectangle Name="rect1">
<Rectangle.Fill>
<SolidColorBrush x:Name="rosyBrush" Color="RosyBrown"/>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Trigger.EnterActions>
<BeginStoryboard Name="bst2">
<Storyboard AutoReverse="False">
<ColorAnimation Duration="0:0:.3"
Storyboard.TargetProperty="Color"
Storyboard.TargetName="rosyBrush" >
<ColorAnimation.By>
<Color A="0" R="100" B="0" G="0"/>
</ColorAnimation.By>
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="bst2" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="bst1">
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="Bord1"
Storyboard.TargetProperty="BorderThickness"
By=".1" Duration="0:0:.3" />
<ColorAnimation AutoReverse="False" To="DarkRed" Duration="0:0:.3"
Storyboard.TargetProperty="Color"
Storyboard.TargetName="rosyBrush" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="bst1" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="rect1" Property="Fill" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<Grid>
<Button Template="{StaticResource ResourceKey=ButtonTemplate}" Height="23" Width="100" BorderThickness="2" Name="btnHello" Content="Hello" IsEnabled="False">
</Button>
<ToolBarPanel>
<CheckBox IsChecked="True" Content="Enable Button" Name="cbEnabled" Checked="cbEnabled_Checked" Unchecked="cbEnabled_Checked"/>
</ToolBarPanel>
<my:CustomControl1 Name="customControl11" />
</Grid>
CustomControl1.xaml: (separate assembly)
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:chapter5_3CustomControl">
<Style TargetType="{x:Type local:CustomControl1}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center"
Text="{Binding Path=Time}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CustomControl.cs
public class CustomControl1 : Control
{
public static readonly DependencyProperty TimeProperty;
System.Timers.Timer myTimer = new System.Timers.Timer();
delegate void SetterDelegate();
static CustomControl1()
{
FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
TimeProperty = DependencyProperty.Register("Time", typeof(string), typeof(CustomControl1), metadata);
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public CustomControl1()
{
myTimer.Elapsed += timer_elapsed;
myTimer.Interval = 1000;
myTimer.Start();
this.DataContext = this;
}
void TimeSetter()
{
SetValue(TimeProperty, DateTime.Now.ToLongTimeString());
}
void timer_elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Dispatcher.Invoke(new SetterDelegate(TimeSetter),
System.Windows.Threading.DispatcherPriority.Normal);
}
}
Edit:
I wanted to plug a free tool that I use called snoop! You can find it here, and I recommend it as it allows you to inspect your controls at runtime! Snoop Lives here at time of edit: http://snoopwpf.codeplex.com/ It has saved me a lot of time!
Because your Button and CustomControl are in the same row and column of the Grid, your CustomControl is probably covering the Button. You probably just can't see it.
If you set the Background of your CustomControl to say Red, then you will see what area it is covering.
You would need to ensure that the CustomControl doesn't cover the Button, if you want the Button to respond to mouse events. Alternatively, you can set IsHitTestVisible to false on your CustomControl or ensure it's Background is null.