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.
Related
I am building a WPF application and I would like to have custom MessageBox but I saw that is really tedious and I thought of using the DialogHost provided by MaterialDesign. The problem is that I can't get it to work the way I want it to so let me describe the current behaviour and the wanted one.
The current behaviour:
<materialDesign:ColorZone Grid.Column="1"
Grid.ColumnSpan="2"
Grid.Row="1"
Mode="Light"
Padding="16">
<DockPanel>
<materialDesign:DialogHost DockPanel.Dock="Right">
<Button x:Name="PowerButton"
ToolTip="{Binding PowerButtonToolTip, Source={StaticResource ResourceKey=ButtonsResources}}"
Style="{StaticResource MaterialDesignIconButton}"
Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">
<Button.CommandParameter>
<StackPanel>
<TextBlock Text="TODO" />
<StackPanel Orientation="Horizontal"
Margin="0, 20, 0, 10">
<Button Width="90"
Height="30"
Margin="10, 0, 0, 0"
Style="{StaticResource MaterialDesignOutlinedButton}"
Click="PowerButton_Click">
OK
</Button>
<Button Width="90"
Height="30"
Margin="10, 0, 10, 0"
Style="{StaticResource MaterialDesignOutlinedButton}"
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}">
CANCEL
</Button>
</StackPanel>
</StackPanel>
</Button.CommandParameter>
<materialDesign:PackIcon Kind="Power" />
</Button>
</materialDesign:DialogHost>
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="MenuButton"
Style="{DynamicResource MaterialDesignHamburgerToggleButton}" />
<TextBlock VerticalAlignment="Center"
Margin="16 0 0 0"
Text="{Binding MainViewTitle, Source={StaticResource ResourceKey=ViewsResources}}">
</TextBlock>
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
What happens is that when I'm clicking the PowerButton the DialogHost appears with the structure from the Button.CommandParameter. The issue with this is that the window doesn't get "disabled" (getting a little black and unclickable) while the dialogue is on.
I saw that to achieve this behaviour I need to but all the content of the window inside the DialogHost. But is it really so or I am misunderstanding something? Their example (see link) isn't really helpful because there seem to be other things running in the background. Moreover, the command materialDesign:DialogHost.OpenDialogCommand of the button that is opening the "Topmost dialogue host" seems limited to me.
Let's try something simple fo you to try at the first time.
The DialogHost is composed of two major parts
First everything that is displayed into your DialogHost, this have to be into one block (StackPanel, Grid, DockPanel...) that is the content of your DialogHost.
Second part is more like the context of your dialog, when you want to display it have to be somewhere to be displayed, another block (StackPanel, Grid, DockPanel...), the context is the place where your dialog will be once displayed, il will show centered and darken the rest of the block.
Now you have the main theory let's make a simple sample based on the sample given by the demo and your piece of code.
<materialDesign:DialogHost HorizontalAlignment="Center" VerticalAlignment="Center">
<materialDesign:DialogHost.DialogContent>
<StackPanel Margin="16">
<!-- HERE GOES YOUR CONTENT -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" >
<Button Style="{StaticResource MaterialDesignFlatButton}" IsDefault="True"
Margin="0 8 8 0" Command="materialDesign:DialogHost.CloseDialogCommand">
<Button.CommandParameter>
<system:Boolean>True</system:Boolean>
</Button.CommandParameter>
ACCEPT
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}"
IsCancel="True" Margin="0 8 8 0"
Command="materialDesign:DialogHost.CloseDialogCommand">
<Button.CommandParameter>
<system:Boolean>False</system:Boolean>
</Button.CommandParameter>
CANCEL
</Button>
</StackPanel>
</StackPanel>
</materialDesign:DialogHost.DialogContent>
<!-- START OF YOUR CONTEXT-->
<!-- END OF YOUR CONTEXT -->
</materialDesign:DialogHost>
So now you have the basis that may be enough for you to start enjoying.
A little more, your context need to be large enough to display what you put on your DialogHost so you can't put a whole dialog around a button, it is better to make it around something bigger, as a first try you should try on a new page to test this context :
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Button x:Name="PowerButton" ToolTip="{Binding PowerButtonToolTip, Source={StaticResource ResourceKey=ButtonsResources}}"
Style="{StaticResource MaterialDesignIconButton}"
Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}">
</Grid>
The Buttons under the content are simply there if you desire to do an action, for example if the DialogHost is there for a modification or a choice where the user can say Yes or No then rename ACCEPT and CANCEL as you want. The "IsDefault" is there to make that it is this button that is considered as pressed if the user press Enter. Pressing a button automatically close the Dialog that is good to know.
And as the both ACCEPT and CANCEL are button you can affect a Click event that will be pretty useful for advanced using of the DialogHost.
I am trying to build Windows-10(UWP) app. My app has 4 buttons which appear at the bottom of the screen.
Button1, 2 & 4 are in their intended position. I want to place Button3 in between Button2 & Button4. How can I achieve that with RelativePanel in UWP?
My xaml code snippet for Button3 is
<Button Name="BtnTextSearchLaunch" Content="Text Search" RelativePanel.AlignVerticalCenterWith="Button2" Width="60" Background="#FF291313" Height="30" RelativePanel.RightOf="Button2" >
<Button.Template>
<ControlTemplate>
<Image Source="/Assets/textSearch#2x.png"/>
</ControlTemplate>
</Button.Template>
</Button>
I can place Button3 in the required position by specifying the position as in Margin="a,b,c,d", but that doesnt work well if I run the app on mobile. Hence I want to achieve this with RelativePanel, since that would scale the UI dynamically & give me the ability to deploy my app on Local Machine as well as Mobile.
<Grid HorizontalAlignment="Stretch" >
<RelativePanel VerticalAlignment="Center" HorizontalAlignment="Stretch" >
<Button x:Name="btn1" Content="btn1" RelativePanel.AlignLeftWithPanel="True" HorizontalAlignment="Left" />
<Button x:Name="btn2" Content="btn2" RelativePanel.AlignHorizontalCenterWithPanel="True" HorizontalAlignment="Center" />
<Button x:Name="btn3" Content="btn3" RelativePanel.RightOf="btn2" RelativePanel.LeftOf="btn4" HorizontalAlignment="Center" />
<Button x:Name="btn4" Content="btn4" RelativePanel.AlignRightWithPanel="True" HorizontalAlignment="Right" />
</RelativePanel>
</Grid>
As you can see from the solution you just need to make sure you place the button relative to both the btn2 and btn4 and don't forget to specify HorizontalAlignment="Center".
I want tot use only pictures in the header of the tabcontrol.
I'm using like this:
<TabItem.Header>
<Image Name="ImageClientPoints" Width="150" Height="80"
Stretch="Fill" Margin="0,0,0,0" />
</TabItem.Header>
and the result is the following:
http://oi39.tinypic.com/x3hnc9.jpg
but I want only the picture without the grey content around the picture.
I'm new to wpf i read about it and as I know I have to create a datatemplate for this but it's to hard to me yet, an example would be helpful.
You are almost there. It seems header have some kind of padding reserved. So set the margin value to some negative value to overlap that padding space.
This will do for you -
<TabItem.Header>
<Image Name="ImageClientPoints" Width="150" Height="80"
Stretch="Fill" Margin="-5" />
</TabItem.Header>
OR
<TabItem.HeaderTemplate>
<DataTemplate>
<Image Name="ImageClientPoints" Width="150" Height="80"
Stretch="Fill" Margin="-5" />
</DataTemplate>
</TabItem.HeaderTemplate>
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.
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??