i have the following DataTemplate which is defined in a Resources.xaml which holds my Visual Templates for my programs (thats why no Eventhandlers are included here)
<DataTemplate x:Key="PointTemplate">
<Ellipse x:Name="Ellipse" Width="8" Height="8" Stroke="Black" StrokeThickness="1.5" Fill="White" Visibility="{Binding DataItem.Visibility}"/>
</DataTemplate>
then its used for a visual in Code by loading it from my Resources:
...
line.PointTemplate = (DataTemplate) Application.Current.Resources["PointTemplate"];
Now i want to add an EventHandler and Cursor to the Ellipse inside the PointTemplate (=DataTemplate).
but.. how do i do this?
thanks in advance!
One of the ways to handle the event is to use a Button with a command:
<DataTemplate x:Key="PointTemplate">
<Button Command="Zoom">
<Button.Template>
<ControlTemplate>
<Ellipse x:Name="Ellipse" Width="80" Height="80" Stroke="Black" StrokeThickness="1.5" Fill="White"/>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
And you can add a handler for the command accordingly.
Related
I am new to WPF an creating a application where I want to make a generic layout which could be applied for all windows.I want few buttons and window properties to be comman on all windows.
Please help if this is possible.I am unable to find any link or source where this sort of functionality is explained.
Many Thanks.
*****Edit****
I am using this code which shows a button on window.I dont want to write it on all windows.I want to place in base/parent so that it appears on all windows which i add to project and inherit from the base/parent class.
But How? I have got very little idea.Any help is appreciated.
<Controls:MetroWindow.RightWindowCommands>
<Controls:WindowCommands>
<Button Content="settings" Name="Settings" Click="Settings_Click" />
<Button>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_cupcake}" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="4 0 0 0" VerticalAlignment="Center" Text="test" />
</StackPanel>
</Button>
</Controls:WindowCommands>
</Controls:MetroWindow.RightWindowCommands>
Yes you can do it.. there is a term called UserControl you have to write your own UserControl.
For basic how to write re-usable UserControl. check the given link
Its not the control you want.. but you can get an idea how to write UserControl.. :)
For creating a common theme for the whole application you should look in the direction of Styles and Shared Resources, see here http://msdn.microsoft.com/en-us/library/ms745683(v=vs.110).aspx
Or you can use ready-made Themes, like here http://wpfthemes.codeplex.com/
EDIT
You can achieve this by moving the common controls which should be used in all windows to a separate UserControl. So then you will have smth like this:
UserControl
<StackPanel>
<Button Content="settings" Name="Settings" />
<Button>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="4 0 0 0" VerticalAlignment="Center" Text="test" />
</StackPanel>
</Button>
</StackPanel>
Then to all the windows where you need these controls you should add this control, like this:
<local:UserControl1 x:Name="myCtrl"></local:UserControl1>
where local is the namespace where the UserControl1 is defined.
I have a basic WPF windows with the markup as specific below:
<Window x:Class="Application.SomeWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SomeWindow"
Topmost="True" WindowStyle="None" Height="39" Width="400"
ResizeMode="NoResize" ShowInTaskbar="False"
WindowStartupLocation="Manual" Background="Transparent"
Closing="Window_Closing" AllowsTransparency="True" Opacity="0">
<Border Background="CornflowerBlue" BorderBrush="Black" BorderThickness="0,0,0,0" CornerRadius="5,5,5,5" Opacity="0.75">
<Grid>
<!-- Display bar -->
<Image Grid.Row="1" Height="24" Margin="7,7,0,0" Name="img1" Stretch="Fill" VerticalAlignment="Top" Source="/Application;component/Images/dashboard/1.png" HorizontalAlignment="Left" Width="13" />
<Image Height="24" Margin="19,7,47,0" Name="image21" Source="/Application;component/Images/dashboard/2.png" Stretch="Fill" VerticalAlignment="Top" Grid.Row="1" Grid.ColumnSpan="2" />
<!-- Button 1 -->
<Button Style="{DynamicResource NoChromeButton}" Height="27" Margin="0,5,25,0" Name="btn1" Click="btn1_Click" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Width="23" ToolTip="1">
<Image Height="26" HorizontalAlignment="Right" Name="img1" Source="/Application;component/Images/dashboard/3.png" VerticalAlignment="Top" Width="22" Stretch="Fill" />
</Button>
<!-- Button 2 -->
<Button Style="{DynamicResource NoChromeButton}" Height="27" Margin="0,5,5,0" Name="btn2" Click="btn2_Click" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Width="23" ToolTip="2">
<Image Height="26" HorizontalAlignment="Right" Name="img2" Source="/Application;component/Images/dashboard/4.png" VerticalAlignment="Top" Width="22" Stretch="Fill" />
</Button>
</Grid>
</Border>
</Window>
Here is what it looks like now:
What I'd really like to do is make it so that initially looks like this:
Then, once mouseover happens, to fade background opacity in from 0 so it looks like the first image. The problem is that if I set the Border or Grid Background color to Transparent with the goal of fading in on mouseover, then everything inside the Border or Grid is affected as well.
Is there a way to manage the opacities of window and its UI elements seperately? Or perhaps there is a totally different route to take to get this background fade on mouseover? Thanks.
There are two options. Number one is to just move the outer border inside the grid, as the first child (and have the other controls alongside it, not in it). That way it will fade by itself, but still be behind the other controls. You will of course either have to set ColumnSpan/RowSpan, or wrap the entire thing in another Grid.
The second option is to just fade the background, not the entire border:
<Border ...>
<Border.Background>
<SolidColorBrush Color="CornflowerBlue" Opacity="0.5"/>
</Border.Background>
...
try this trick - draw a rectangle or border with dimensions bind to parent or ElementName.
It won't affect rest of elements of tree. Works for me.
<Grid x:Name="abc">
<Border
Width="{Binding ActualWidth, ElementName=abc}"
Height="{Binding ActualHeight, ElementName=abc}"
Background="Blue"
Opacity="0.5"/>
//buttons or inner grid
...
</Grid>
If you don'w want to use ElementName, simply replace Width and Height by
Width="{Binding ActualWidth, Source={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
Height="{Binding ActualHeight, Source={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
I'm having a lot of trouble trying to get this working, and was hoping someone could help.
I have a ScrollViewer in my WindowsPhone app, and I'm trying to emulate a similar control to the "Date/Time Chooser" that you'd see in the native Calendar app. So my ScrollViewer contains a StackPanel with multiple square Canvases with rectangles and TextBlocks. My intent is to watch the "ScrollStates", and when the VisualState changes to "NotScrolling", I'd then check the VerticalOffset of the ScrollViewer and animate a slide to the nearest "snap-to" position (ie. aligning the square to the correct/middle position).
<ScrollViewer Name="sv" Width="100" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Disabled" Loaded="ScrollViewer_Loaded">
<StackPanel>
<Canvas MaxWidth="77" MaxHeight="80" MinWidth="80" MinHeight="80" Margin="3">
<Rectangle Stroke="{StaticResource PhoneForegroundBrush}" StrokeThickness="3" Width="80" Height="80" />
<TextBlock Text="1" FontSize="36" FontWeight="Bold" TextAlignment="Center" HorizontalAlignment="Center" Width="70" Canvas.Left="6" Canvas.Top="14" LineHeight="48" />
</Canvas>
<Canvas MaxWidth="77" MaxHeight="80" MinWidth="80" MinHeight="80" Margin="3">
<Rectangle Stroke="{StaticResource PhoneForegroundBrush}" StrokeThickness="3" Width="80" Height="80" />
<TextBlock Text="2" FontSize="36" FontWeight="Bold" TextAlignment="Center" HorizontalAlignment="Center" Width="70" Canvas.Left="6" Canvas.Top="14" LineHeight="48" />
</Canvas>
<Canvas MaxWidth="77" MaxHeight="80" MinWidth="80" MinHeight="80" Margin="3">
<Rectangle Stroke="{StaticResource PhoneForegroundBrush}" StrokeThickness="3" Width="80" Height="80" />
<TextBlock Text="3" FontSize="36" FontWeight="Bold" TextAlignment="Center" HorizontalAlignment="Center" Width="70" Canvas.Left="6" Canvas.Top="14" LineHeight="48" />
</Canvas>
...
</StackPanel>
</ScrollViewer>
I've been looking at various examples that hook into the VisualStates, like http://blogs.msdn.com/b/ptorr/archive/2010/07/23/how-to-detect-when-a-list-is-scrolling-or-not.aspx ; http://developingfor.net/2009/02/16/fun-with-the-wpf-scrollviewer/ ; http://blogs.msdn.com/b/slmperf/archive/2011/06/30/windows-phone-mango-change-listbox-how-to-detect-compression-end-of-scroll-states.aspx ... all seem to have similar code to this:
// Visual States are always on the first child of the control template
FrameworkElement element = VisualTreeHelper.GetChild(sv, 0) as FrameworkElement;
... which then goes on to seek out VisualStateGroup group = FindVisualState(element, "ScrollStates");, from which they can hook an Event to when it changes.
However... whenever I try doing the VisualTreeHelper.GetChild(sv,0) as FrameworkElement, the app crashes with an exception of type 'System.ArgumentOutOfRangeException'. If I output VisualTreeHelper.GetChildrenCount(sv), it is always "0". How is it seemingly working for everyone else? 8)
Any help would be greatly appreciated. Thanks!
(As an alternative, has anyone made this kind of "Select Box" already in a reusable control I could use instead of trying to reinvent it?)
Did you wait till the scrollviewer's Loaded event fires before trying to get the scrollviewer children??
I want to alter the styling of some WPF tab headers. I would like to keep all the original styling of the tab headers, except for these three things -
Increase the height of the headers
Make the heights of each header the same. Normally the selected tab has a bigger height, I need the heights of both selected and unselected tabs to be the same.
Add a picture above the text on each header
Here is a before and after image of what I am looking to do -
Anyone know how to do this?
There you go, you can replace Stack panel with your nice images.
Update 1- in order to remove sizing effect when seelcting a tab you'll need to alter the TabItem style (header template is too light for it). Just get a StyleSnooper (http://blog.wpfwonderland.com/2007/01/02/wpf-tools-stylesnooper/) open it with VS2010 recompile it for .NET4, launch, navigate to TabItem and search for:
<Setter Property="FrameworkElement.Margin">
<Setter.Value>
<Thickness>
2,2,2,2</Thickness>
</Setter.Value>
</Setter>
<Setter Property="FrameworkElement.Margin" TargetName="Content">
<Setter.Value>
<Thickness>
2,2,2,2</Thickness>
</Setter.Value>
margins are the values you want to change to fix your 2. Then just put the modified version into the resources, so the app can pick it up. The style contains a lot of handy stuff you can tweak.
<Window x:Class="Immutables.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">
<Grid>
<TabControl TabStripPlacement="Left" x:Name="AreasTabControl" Margin="1">
<TabItem x:Name="AttributesTab">
<TabItem.HeaderTemplate>
<DataTemplate>
<Grid Width="100" Height="40">
<Border BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal">
<Rectangle VerticalAlignment="Top"
Width="5" Height="5" Fill="White" />
<Rectangle VerticalAlignment="Top"
Width="5" Height="5" Fill="Blue" />
<Rectangle VerticalAlignment="Top"
Width="5" Height="5" Fill="Red" />
</StackPanel>
</Border>
<TextBlock Margin="0,20,0,0">Go Russia!</TextBlock>
</Grid>
</DataTemplate>
</TabItem.HeaderTemplate>
</TabItem>
</TabControl>
</Grid>
</Window>
I have a MediaElement object in my XAML, which loads my movie just fine. What I want to do is render the play, pause and stop buttons right in the center my MediaElement object, kind of like how if you embed a YouTube video on a web page, you get the big play button in the center of the video. Can I do this in WPF using MediaElement?
In case anyone else ever needs to do this, I figured it out. I simply created a Canvas and stuck the MediaElement and the Button both inside the Canvas. I then used ZIndex to change the ZOrdering so the button was on top. Finally, I centered the button on top of my movie. Here is the XAML:
<StackPanel Orientation="Horizontal" Background="LightGray" DockPanel.Dock="Bottom" Height="100">
<Canvas Width="100">
<Button Canvas.ZIndex="2" Canvas.Left="42" Canvas.Top="35">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Polygon Points="0,0 0,26 17,13" Fill="#80000000" Stroke="White" />
</ControlTemplate>
</Button.Template>
</Button>
<MediaElement Canvas.ZIndex="1" Canvas.Top="0" Canvas.Left="0"
x:Name="mediaElement1" UnloadedBehavior="Manual" LoadedBehavior="Manual" ScrubbingEnabled="True"
Loaded="mediaElement1_Loaded" Width="100" Height="100">
</MediaElement>
</Canvas>
</StackPanel>
Or you need to place mediaElement and Buttons to same Grid and set Canvas.ZIndex to higher number than 0:
<Grid>
<Button VerticalAlignment="Center" HorizontalAlignment="Center" Height="50" Width="100" Canvas.ZIndex="1">Button</Button>
<MediaElement Source="/Assets/ladybug.wmv">
</MediaElement>
</Grid>
(actually you don't need Canvas [works on UWP]):