This is an old revision of the document!
WPF Basic Controls
Border
Border
control with rounder corners:
<Border CornerRadius="12,12,0,0" BorderThickness="0" BorderBrush="Gray" Background="DarkGray">
Border
control using Style
to apply rounded corners:
<Window> <Window.Resources> <Style x:Key="RoundedBorder" TargetType="Border"> <Setter Property="CornerRadius" Value="12,12,0,0"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="BorderBrush" Value="Gray"/> <Setter Property="Background" Value="DarkGray"/> </Style> </Window.Resources> <Border Grid.Column="1" Grid.Row="1" Height="119" HorizontalAlignment="Right" Margin="0,64,30,0" Name="border1" VerticalAlignment="Top" Width="103" Style="{StaticResource RoundedBorder}" /> </Window>
Border
with header region:
<Border Name="borderContainer" Grid.Column="1" Grid.Row="1" Margin="124,168,118,126" CornerRadius="10" Background="LightBlue" BorderThickness="0" BorderBrush="Transparent" > <Border Name="borderHeader" Height="20" VerticalAlignment="Top" CornerRadius="10,10,0,0"> <Border.Background> <ImageBrush ImageSource="toolbar-bg-img.jpg"/> </Border.Background> </Border> </Border>
Border
with some style:
<Grid> <Border CornerRadius="5" BorderBrush="Black" BorderThickness="5" Width="300" Height="400" HorizontalAlignment="Center" Background="#FFFFFFFF"> <StackPanel> <Border Height="30"> <Border.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FF4C4C4C"/> <GradientStop Color="#FF333538" Offset="1"/> <GradientStop Color="#FF3C3D3F" Offset="0.394"/> <GradientStop Color="#FF151516" Offset="0.417"/> </LinearGradientBrush> </Border.Background> <TextBlock Text="Data from an XML file:" Margin="10 5" Foreground="#FFFFFFFF" FontSize="13" /> </Border> <TextBlock>Data Here...</TextBlock> </StackPanel> </Border> </Grid>
Border
with DropShadowEffect
:
<Border CornerRadius="5" BorderBrush="LightGray" BorderThickness="1" Background="White" Margin="10"> <Border.Effect> <DropShadowEffect Opacity="0.5" ShadowDepth="5" BlurRadius="20" /> </Border.Effect> <Image Width="150" Height="150" Margin="5" Source="/images/worldmap.png" /> </Border>
Button or ToggleButton
Standard button:
<Button Content="A Button" .... />
Toggle button:
<ToggleButton IsChecked="False" ... />
Button with gradient background:
<Button Margin="41.25,35,45,0" Height="40" VerticalAlignment="Top" Click="Button_Click" BorderThickness="2" FontSize="15"> <Button.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Red" Offset="0" /> <GradientStop Color="Yellow" Offset="0.25" /> <GradientStop Color="Green" Offset="0.75" /> <GradientStop Color ="Blue" Offset="1" /> </LinearGradientBrush> </Button.Background> ColorFull Button </Button>
Button with gradient background style:
<Application.Resources> <LinearGradientBrush x:Key="GrayBlueGradientBrush" StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="DarkGray" Offset="0" /> <GradientStop Color="#CCCCFF" Offset="0.5" /> <GradientStop Color="DarkGray" Offset="1" /> </LinearGradientBrush> <Style TargetType="{x:Type Button}"> <Setter Property="Background" Value="{StaticResource GrayBlueGradientBrush}" /> <Setter Property="Width" Value="80" /> <Setter Property="Margin" Value="10" /> <Setter Property="Template"> <Setter.Value> <!-- The button template is defined here. --> </Setter.Value> </Setter> </Style> </Application.Resources> ... <Button Name="btnTest">Test</Button>
A Button
with shadow bitmap effect:
<Button Margin="50" Width="200"> DropShadow Under this Button <Button.BitmapEffect> <!-- <BitmapEffectGroup> would go here if you wanted to apply more then one effect to the Button. However, in this example only one effect is being applied so BitmapEffectGroup does not need to be included. --> <DropShadowBitmapEffect Color="Black" Direction="320" ShadowDepth="25" Softness="1" Opacity="0.5"/> </Button.BitmapEffect> </Button> <Button Margin="50" Width="200"> OK <Button.BitmapEffect> <!-- <BitmapEffectGroup > -- Deprecated, in favor of Effect --> <!--<OuterGlowBitmapEffect GlowColor="Yellow" GlowSize="10"/> -- Deprecated, in favor of BlurEffect --> <DropShadowBitmapEffect Color="Red" ShadowDepth="5" /> <!-- The larger the Radius, the more blurring. The default range is 20. In addition, the KernelType is set to a box kernel. A box kernel creates less disruption (less blur) then the default Gaussian kernel. --> <!-- <BlurBitmapEffect Radius="10" KernelType="Box" /> --> <!-- </BitmapEffectGroup> --> </Button.BitmapEffect> </Button>
A button style:
<Style x:Key="SideButtonStyle" TargetType="Button"> <Setter Property="FontFamily" Value="Segoe UI" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="Foreground" Value="White" /> <Setter Property="Margin" Value="4,4,0,4" /> <Setter Property="Padding" Value="5" /> <Setter Property="Width" Value="100" /> <Setter Property="Height" Value="60" /> <Setter Property="BitmapEffect"> <Setter.Value> <BitmapEffectGroup> <OuterGlowBitmapEffect/> <DropShadowBitmapEffect/> </BitmapEffectGroup> </Setter.Value> </Setter> </Style>
Possible bitmap effects:
DropShadowEffect
BlurEffect
Reflection effect:
For programmatically clicking on a button:
myButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
Tooltips on a button:
<Button Content="Tooltip Test" ToolTipService.InitialShowDelay="1" ToolTipService.BetweenShowDelay="1" ToolTipService.ShowDuration="30000"> <Button.ToolTip> <StackPanel Background="White"> <Label FontWeight="Bold" Background="SteelBlue" Foreground="White" Content="Sample ToolTip Header"/> <TextBlock Width="200" TextWrapping="Wrap" Text="Sample ToolTip Body"/> </StackPanel> </Button.ToolTip> </Button>
More Creative:
Cursor
Changing cursors programmatically (eg: pen, cross, scroll, etc.):
this.Cursor = Cursors.None;
Using custom cursors:
this.Cursor = new Cursor("CustomCursorImage.jpg");
Using custom cursors via XAML:
<Button Content="Wait" Cursor="Wait"/> <Button Content="CustomCursorImage.jpg"/>
DataGrid
Types of columns
- DataGridTextColumn: For string values.
- DataGridCheckBoxColumn: For boolean values.
- DataGridComboBoxColumn: For enumerated types, or lists.
- DataGridHyperlinkColumn: For URI values.
- DataGridTemplateColumn: For custom fields.
Attributes:
- CanUserAddRows: Activates additional empty row at the bottom.
- IsReadOnly: Set grid to read only.
- FrozenColumnCount: Set the number of columns to freeze on the left side.
- IsSynchronizedWithCurrentItem: Set synchronization with DataContext or other data binding method, so that other controls using that data bind will be synchronized as well.
- AlternatingRowBackground: Sets color for alternating background.
- AlternationCount: Set number of rows before alternating colors.
XAML:
<UserControl ...> <UserControl.Resources> <!--Data Providers--> <ObjectDataProvider x:Key="objDataProviderTProductSpecificationList" ObjectType="{x:Type local:TProductSpecificationList}" /> <UserControl.Resources> <Grid> <TextBlock FontWeight="Bold">Product Specifications Matrix</TextBlock> <DataGrid Name="datagridProdList" ItemsSource="{Binding Source={StaticResource objDataProviderTProductSpecificationList}}" CanUserAddRows="False" IsReadOnly="True" FrozenColumnCount="1" IsSynchronizedWithCurrentItem="True" AlternatingRowBackground="AliceBlue" Margin="5" AutoGenerateColumns="False" > <DataGrid.Columns> <DataGridTemplateColumn Header="Name"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="{Binding Path=Name}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> <DataGridTextColumn Binding="{Binding MarketSegmentName}" Header="Market Segment" /> <DataGridTextColumn Binding="{Binding StyleName}" Header="Style" /> <DataGridTextColumn Binding="{Binding Channels}" Header="Channels" /> <DataGridTextColumn Binding="{Binding AutoEnvironmentSwitching}" Header="Auto Env" /> <DataGridTextColumn Binding="{Binding AdaptiveDirectionalChannels}" Header="Adapt Dir Ch" /> <DataGridTextColumn Binding="{Binding NoiseReductionsBands}" Header="NR Bands" /> <DataGridCheckBoxColumn Binding="{Binding BluetoothCompatible}" Header="Bluetooth" /> <DataGridCheckBoxColumn Binding="{Binding AudioLoopSystemCompatible}" Header="Audio Loop Sys" /> <DataGridCheckBoxColumn Binding="{Binding FMLoopSystemCompatible}" Header="FM Loop Sys" /> <DataGridCheckBoxColumn Binding="{Binding PhoneLoopSystemCompatible}" Header="Phone Loop Sys" /> <DataGridCheckBoxColumn Binding="{Binding AdaptiveFeedbackCanceller}" Header="Adapt FBC" /> <DataGridTextColumn Binding="{Binding DataloggerTypeName}" Header="Datalogger" /> <DataGridCheckBoxColumn Binding="{Binding WindManager}" Header="Wind Mgr" /> <DataGridCheckBoxColumn Binding="{Binding TinnitusNoiseGenerator}" Header="Tinnitus Noise Gen" /> <DataGridTextColumn Binding="{Binding ManualPrograms}" Header="Programs" /> <DataGridTemplateColumn Header="Housing" > <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Image Source="{Binding Path=HousingImgFilename}" Width="40"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> <Grid> </UserControl>
To add a row programmatically:
DataGrid.Items.Add(new DataItem());
To add a column programmatically:
DataGrid.Columns.Add(new DataGridTextColumn());
To add data to DataGrid
programmatically:
... // assuming x:Name="myGrid" in markup // add rows to grid (same logic for columns as well) for (int row=0; row < numRows; row++) { myGrid = RowDefinitions.Add(new RowDefinition()); } // Stick a control in intended location b = new Button(); myGrid.Children.Add(b); Grid.SetRow(b,1); // 2nd row Grid.SetColumn(b,3); // 4th column Grid.SetColumnSpan(b,2); b.Style = (Style)FindResource("myButtonStyle"); // defined in MyApp.xaml ...
Expander
Expander with a ListBox inside:
<Expander Name="expPatients" Header="Patients" Margin="0" BorderThickness="1" IsExpanded="True" Background="Transparent" BorderBrush="Transparent" Grid.Row="1"> <Border CornerRadius="12,12,0,0" BorderThickness="0" BorderBrush="Gray" Background="DarkGray"> <Grid> <ListBox Margin="0,13,0,0" Name="lstPatients" BorderThickness="0" Opacity="0.7" /> </Grid> </Border> </Expander>
Modify Expander header style:
<Expander Name="expPatients" Margin="0" BorderThickness="1" IsExpanded="True" Background="Transparent" BorderBrush="Transparent" Grid.Row="1"> <Expander.Header> <Border BorderBrush="Navy" BorderThickness="2" CornerRadius="6"> <TextBlock Margin="10,2,10,2" Foreground="Navy">Patients</TextBlock> </Border> </Expander.Header> <Expander.Content> <Border CornerRadius="12,12,0,0" BorderThickness="0" BorderBrush="Gray" Background="DarkGray"> </Expander.Content> </Expander>
Expander with Popup content:
<Grid Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition Height="33" /> <RowDefinition /> </Grid.RowDefinitions> <Canvas Panel.ZIndex="99"> <Expander HorizontalAlignment="Left" Header="PopUp Window Expander" VerticalAlignment="Top" ExpandDirection="Down" Width="175"> <Grid Background="Cornsilk"> <Grid.BitmapEffect> <DropShadowBitmapEffect /> </Grid.BitmapEffect> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Text="How Cool Is This!" FontWeight="Bold" Margin="5"/> <TextBlock Grid.Row="1" TextWrapping="Wrap" Margin="5"> This is the popup expander behavior. The expander opens and overlays the controls below it. </TextBlock> </Grid> </Expander> </Canvas> <StackPanel Grid.Row="1" Margin="10,5,0,0"> <RadioButton Content="Choice One"/> <RadioButton Content="Choice Two"/> <RadioButton Content="Choice Three"/> </StackPanel> </Grid>
Resources:
FlowDocument
Example of FlowDocument
contained in FlowDocumentReader
control:
<Window x:Class="FlowDocReader.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:bt="clr-namespace:AcmeWPF.BindableText;assembly=AcmeWPF" Title="MainWindow" Height="650" Width="825"> <Grid> <FlowDocumentReader Name="flowdocReportViewer" ViewingMode="TwoPage"> <FlowDocument Name="flowdocReport" FontFamily="Arial"> <!--Document Header--> <Section LineHeight="2" Background="Beige" Foreground="Brown"> <Paragraph FontSize="34" FontFamily="AquilineTwo">Main Report</Paragraph> </Section> <!--Document Content--> <Paragraph>Patient Details</Paragraph> <List> <ListItem> <Paragraph>Name: John Doe</Paragraph> </ListItem> <ListItem> <Paragraph>Address: 1250 Main Street, Orange, FL 32700</Paragraph> </ListItem> <ListItem> <Paragraph> <bt:BindableRun BoundText="{Binding Path=User.Name}" /> <TextBlock Text="{Binding Path=CreatedDate}"/> </Paragraph> </ListItem> </List> <!--Embedded UI Controls--> <BlockUIContainer> <Viewbox> <CheckBox>Tested Binaurally</CheckBox> </Viewbox> </BlockUIContainer> <!--Table--> <Table BorderThickness="1" BorderBrush="Gray"> <Table.Columns> <TableColumn/> <TableColumn/> <TableColumn/> </Table.Columns> <TableRowGroup> <!--Row 1--> <TableRow> <TableCell BorderBrush="Gray" BorderThickness="1"> <Paragraph>Left</Paragraph> </TableCell> <TableCell BorderBrush="Gray" BorderThickness="1"> <Paragraph>Right</Paragraph> </TableCell> <TableCell BorderBrush="Gray" BorderThickness="1"> <Paragraph>Both</Paragraph> </TableCell> </TableRow> <!--Row 2--> <TableRow> <TableCell> <Paragraph>X</Paragraph> </TableCell> <TableCell> <Paragraph>X</Paragraph> </TableCell> <TableCell> <Paragraph>X</Paragraph> </TableCell> </TableRow> <!--Row 3--> <TableRow> <TableCell> <Paragraph>Y</Paragraph> </TableCell> <TableCell> <Paragraph>Y</Paragraph> </TableCell> <TableCell> <Paragraph>Y</Paragraph> </TableCell> </TableRow> </TableRowGroup> </Table> <!--New Page--> <Paragraph BreakPageBefore="True">New Page Here</Paragraph> <!--URL--> <Paragraph> <Hyperlink NavigateUri="http://www.google.com">Google Search</Hyperlink> </Paragraph> </FlowDocument> </FlowDocumentReader> </Grid> </Window>
More in depth:
A FlowDocument
can also be at the layout root:
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Section ....></Section> <Paragraph>...</Paragraph> ... </FlowDocument>
You can print it using:
// Print Document PrintDialog dlg = new PrintDialog(); dlg.PrintDocument(((IDocumentPaginatorSource)flowdocReport).DocumentPaginator, "Main Report");
For printing FlowDocuments and data binding, see Introducing Tweet Sandwich
You can load a xaml file dynamically:
void LoadFlowDocumentScrollViewerWithXAMLFile(string fileName) { // Open the file that contains the FlowDocument... System.IO.FileStream xamlFile = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); // Parse the file with the XamlReader.Load method. FlowDocument content = System.Windows.Markup.XamlReader.Load(xamlFile) as FlowDocument; // Alternatively: // If the FlowDocument references external resources (such as image files) using // relative uniform resource identifiers (URIs), it is necessary to specify a // ParserContext that includes a BaseUri so that the parser can make sense of the // relative URIs. The XamlReader class provides Load method that accepts a ParserContext. //FlowDocument content = System.Windows.Markup.XamlReader.Load(xamlFile, // new System.Windows.Markup.ParserContext() { BaseUri = new Uri("/images/icons/") } ) as FlowDocument; // Finally, set the Document property to the FlowDocument object that was // parsed from the input file. flowdocReportViewer.Document = content; xamlFile.Close(); }
Source: MSDN: How to: Load a XAML File into a FlowDocumentScrollViewer
To make use of bindable text, make sure to include this:
using System; using System.Windows; using System.Windows.Documents; namespace AHI.App.Tools { ///-------------------------------------------------------------------------------------------- /// <summary> /// A subclass of the Run element that exposes a DependencyProperty property /// to allow data binding. /// Source: Filipe Fortes, BindableRun, http://www.fortes.com/2007/bindablerun ///-------------------------------------------------------------------------------------------- /// Usage: /// <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" /// xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" /// xmlns:bt="clr-namespace:BindableText;assembly=BindableText"> /// <FlowDocumentScrollViewer> /// <FlowDocument> /// <Paragraph> /// You can control the value of this text through the TextBox below: /// <bt:BindableRun FontWeight="Bold" BoundText="{Binding ElementName=tb, Path=Text}" /> /// </Paragraph> /// <BlockUIContainer> /// <TextBox Name="tb" Text="This is text with spaces that wraps across a line ... like this!"/> /// </BlockUIContainer> /// </FlowDocument> /// </FlowDocumentScrollViewer> /// </Page> /// /// </summary> ///-------------------------------------------------------------------------------------------- public class TBindableRun : Run { public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register( "BoundText", typeof(string), typeof(TBindableRun), new PropertyMetadata(new PropertyChangedCallback(TBindableRun.onBoundTextChanged)) ); private static void onBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((Run)d).Text = (string)e.NewValue; } public String BoundText { get { return (string)GetValue(BoundTextProperty); } set { SetValue(BoundTextProperty, value); } } } }
GeometryDrawing
Example of GeometryDrawing
embeddeed in Image
control:
<StackPanel> <Canvas> <Image Name="imgInstrumentLinkLeft" Canvas.Top="15" Canvas.Right="0" Visibility="Hidden"> <Image.Source> <DrawingImage> <DrawingImage.Drawing> <DrawingGroup> <GeometryDrawing Geometry="M 0,0 L 20,0"> <GeometryDrawing.Pen> <Pen Brush="SteelBlue" Thickness="1" DashCap="Round" StartLineCap="Triangle" LineJoin="Round" /> </GeometryDrawing.Pen> </GeometryDrawing> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </Image.Source> </Image> <Image Name="imgInstrumentLinkRight" Canvas.Top="5" Canvas.Left="0" Visibility="Hidden"> <Image.Source> <DrawingImage> <DrawingImage.Drawing> <DrawingGroup> <GeometryDrawing Geometry="M 0,0 L 20,0"> <GeometryDrawing.Pen> <Pen Brush="Crimson" Thickness="1" DashCap="Round" EndLineCap="Triangle" LineJoin="Round" /> </GeometryDrawing.Pen> </GeometryDrawing> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </Image.Source> </Image> </Canvas> </StackPanel>
Another example:
<GeometryDrawing Geometry="M 0,0 L 10,0 L 10,25 L 0,25 L 10,25 L 10,48 L 0,48 L 10,48 L 10,68 L 0,68 L 10,68 L 10,90 L 0,90"> <GeometryDrawing.Pen> <Pen Brush="Crimson" Thickness="1" DashCap="Round" EndLineCap="Triangle" LineJoin="Round" /> </GeometryDrawing.Pen> </GeometryDrawing>
As a resource:
<!--================================================================= Basic Geometry Resources (Icons) ==================================================================--> <!--How to use them:--> <!-- DownArrow --> <!--<Path Data="{StaticResource DownArrow}" Width="10" Height="8" Stretch="Fill" Fill="Black" />--> <!-- CloseX --> <!--<Path Data="{StaticResource CloseX}" Width="12" Height="12" Stretch="Fill" Stroke="Black" StrokeThickness="3" Margin="10" />--> <Geometry x:Key="DownArrow">M0,0 L1,0 0.5,1Z</Geometry> <Geometry x:Key="UpArrow">M0,1 L1,1 0.5,0Z</Geometry> <Geometry x:Key="RightArrow">M0,0 L1,0.5 0,1Z</Geometry> <Geometry x:Key="LeftArrow">M0,0.5 L1,1 1,0Z</Geometry> <Geometry x:Key="CloseX">M0,0 L1,1 M0,1 L1,0</Geometry> <Geometry x:Key="Stop">M0,0 L0,1 L1,1 L1,0Z</Geometry>
Grid and GridSplitter
<Grid Name="DynamicGrid" Width="466" Background="LightSteelBlue" ShowGridLines="True" Canvas.Top="100" Canvas.Left="0" Height="200"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="50*" /> <RowDefinition Height="Auto" /> <RowDefinition Height="50*" /> </Grid.RowDefinitions> <GridSplitter ResizeDirection="Rows" Grid.Column="0" Grid.ColumnSpan="10" Grid.Row="1" Width="Auto" Height="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" Background="Green"/> </Grid>
Populating a Grid programmatically
C#:
private void btnAddPanel1_Click() { // How to add a child grid to col 0, row 1, colspan=3 Grid grdPanel1 = new Grid(); grdRoot.Children.Add(grdPanel1); Grid.SetRow(grdPanel1, 1); Grid.SetColumn(grdPanel1, 0); Grid.SetColumnSpan(grdPanel1, 3); // How to add new row definition grdRoot = RowDefinitions.Add(new RowDefinition()); }
Assumming:
<Grid Name="grdRoot"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Button Name="btnAddPanel1" Content="Panel 1" Grid.Column="0" Grid.Row="1" Margin="30" Click="btnAddPanel1_Click"/> <Button Name="btnAddPanel2" Content="Panel 2" Grid.Column="1" Grid.Row="1" Margin="30"/> <Button Name="btnAddPanel3" Content="Panel 3" Grid.Column="2" Grid.Row="1" Margin="30"/> </Grid>
InkCanvas
Setup a space that you can paint at run time:
<InkCanvas Name="icBox" Height="200" />
Image
<Image Name="imgProduct" Source="/images/icons/icon-product.png" Width="40" />
Programmatically (assuming image “Build Action” is set to “Content”):
Image imgProduct = new Image(); //Uri src = new Uri(@"/MyComponentName;component/images/icons/icon-product.png", UriKind.Relative); Uri src = new Uri("/images/icons/icon-product.png", UriKind.RelativeOrAbsolute); BitmapImage img = new BitmapImage(src); imgProduct.Source = img;
Programmatically (assuming image “Build Action” is set to “Resource”):
static internal ImageSource GetImageSourceFromResource(string psAssemblyName, string psResourceName) { Uri oUri = new Uri("pack://application:,,,/" + psAssemblyName + ";component/" + psResourceName, UriKind.RelativeOrAbsolute); return BitmapFrame.Create(oUri); } ... Image imgProduct = new Image(); imgProduct.Source = GetImageSourceFromResource("MyComponentName", @"images/icons/icon-product.png");
When reusing an image, to save memory, create a BitmapSource
as a resource:
<BitmapImage x:Key="MyImageSource" UriSource="/images/img.png" />
Then use it:
<Image Source="{StaticResource MyImageSource}" />
Set the img.png
file's “Build Action” to “Resource” instead of “Content” to embed it with the executable.
Using the Clipboard:
// Copy to Clipboard System.Drawing.Image imgSrc; //... image files with content at some point ... System.IO.MemoryStream fs = new System.IO.MemoryStream(); imgSrc.SaveImage(fs, System.Drawing.Imaging.ImageFormat.Png); System.Drawing.Image imgToCopy = System.Drawing.Image.FromStream(fs); System.Windows.Forms.Clipboard.SetImage(imgToCopy); // Copy from Clipboard imgTarget.Source = Clipboard.GetImage();
ListBox
Normal List:
<ListBox> <ListBox.Items> <TextBlock Text="One" /> <TextBlock Text="Two" /> <TextBlock Text="Three" /> <TextBlock Text="Four" /> </ListBox.Items> </ListBox>
Horizontal List:
<!--Horizontal List--> <!--Source: http://compilewith.net/2008/03/wpf-listbox-itemspaneltemplate-and.html--> <ListBox Grid.Column="0" Grid.Row="0"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.Items> <TextBlock Text="One" /> <TextBlock Text="Two" /> <TextBlock Text="Three" /> <TextBlock Text="Four" /> </ListBox.Items> </ListBox>
Horizontal List with WrapPanel:
<!--Horizontal List with WrapPanel--> <!--Source: http://compilewith.net/2008/03/wpf-listbox-itemspaneltemplate-and.html--> <ListBox Grid.Column="1" Grid.Row="0"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel IsItemsHost="True" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.Items> <TextBlock Text="One" /> <TextBlock Text="Two" /> <TextBlock Text="Three" /> <TextBlock Text="Four" /> <TextBlock Text="Five" /> <TextBlock Text="Six" /> <TextBlock Text="Seven" /> <TextBlock Text="Eight" /> <TextBlock Text="Nine" /> <TextBlock Text="Ten" /> <TextBlock Text="Eleven" /> <TextBlock Text="Twelve" /> </ListBox.Items> </ListBox>
References:
ListView
References:
MediaElement
To play video (or audio) clips, you can use the MediaElement
control.
WPF control:
<MediaElement Name="player" Grid.Column="3" Height="200" LoadedBehavior="Manual"/> <StackPanel Grid.Column="4" VerticalAlignment="Center"> <Button Name="btnPlay" Style="{StaticResource ButtonSimpleStyles}" Content="Play" Click="btnPlay_Click" /> <Button Name="btnStop" Style="{StaticResource ButtonSimpleStyles}" Content="Stop" Click="btnStop_Click" /> </StackPanel>
C# code behind:
private void btnPlay_Click(object sender, RoutedEventArgs e) { player.LoadedBehavior = MediaState.Manual; player.Source = new Uri(@"media\softtouch.wmv", UriKind.Relative); player.Play(); } private void btnStop_Click(object sender, RoutedEventArgs e) { player.Stop(); }
Popup
A button that will open a Popup window when clicked:
<ToggleButton IsChecked="{Binding ElementName=pup, Path=IsOpen}" Content="Open Popup" Margin="100" /> <Popup x:Name="pup" Placement="Bottom" AllowsTransparency="True" PopupAnimation="Fade" VerticalOffset="-100"> <StackPanel> <TextBlock Name="McTextBlock" Background="Black" Foreground="White" > This is popup text </TextBlock> <Button Content="This is button on a Popup" /> </StackPanel> </Popup>
Popup Position Tracking
<UserControl x:Class="MyApp.ucMain" . . . LayoutUpdated="UserControl_LayoutUpdated" Loaded="UserControl_Loaded"> . . . <Button Name="btnHelp" /> <Popup x:Name="popmnuHelp" PlacementTarget="{Binding ElementName=btnHelp}" Placement="Bottom" PopupAnimation="Fade"> <StackPanel Background="White"> <ListBox x:Name="lstMenuHelp" Width="100" SelectionChanged="lstMenuHelp_SelectionChanged"> <ListBoxItem Content="Content"/> <ListBoxItem Content="Support"/> <ListBoxItem Content="Tutorial"/> </ListBox> </StackPanel> </Popup> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; ... namespace ezFIT { /// <summary> /// Interaction logic for ucMain.xaml /// </summary> public partial class ucMain : UserControl { . . . ///---------------------------------------------------------------------------------------- /// <summary> /// Loaded event handler for user control. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> ///---------------------------------------------------------------------------------------- private void UserControl_Loaded(object sender, RoutedEventArgs e) { // Subscribe to SizeChanged and LocationChanged events from parent window, // in order to update popup menus correctly. Window ParentWin = MyLib.App.Tools.TSystemUtils.FindAnchestor<Window>((DependencyObject)e.OriginalSource); ParentWin.SizeChanged += new SizeChangedEventHandler(ParentWin_SizeChanged); ParentWin.LocationChanged += new EventHandler(ParentWin_LocationChanged); } ///---------------------------------------------------------------------------------------- /// <summary> /// LocationChanged event handler used for event subscription by parent window. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> ///---------------------------------------------------------------------------------------- void ParentWin_LocationChanged(object sender, EventArgs e) { ResetPopUp(popmnuHelp); } ///---------------------------------------------------------------------------------------- /// <summary> /// SizeChanged event handler used for event subscription by parent window. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> ///---------------------------------------------------------------------------------------- void ParentWin_SizeChanged(object sender, SizeChangedEventArgs e) { ResetPopUp(popmnuHelp); } ///---------------------------------------------------------------------------------------- /// <summary> /// Reset the specified Popup. /// </summary> /// <param name="aPopup">Popup to reset</param> ///---------------------------------------------------------------------------------------- public void ResetPopUp(Popup aPopup) { Random random = new Random(); aPopup.PlacementRectangle = new Rect( new Point(random.NextDouble() / 1000 /* x coord */, 0 /* y coord */), new Size(100 /* width */, 25 /* height */) ); } . . . } }
Useful links:
Path
To create a geometric figure using Path
:
<UserControl...> <UserControl.Resources> <!--Icons--> <Geometry x:Key="IconArrowUp">M 0 4 L 4 0 L 8 4 Z</Geometry> <Geometry x:Key="IconArrowDown">M 0 0 L 4 4 L 8 0 Z</Geometry> </UserControl.Resources> <Viewbox> <StackPanel> <Button Name="btnUpRight" Width="20" Height="10"> <Button.Content> <Path Name="ArrowUp" Fill="#404040" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 4 L 4 0 L 8 4 Z"/> </Button.Content> </Button> <Button Name="btnUpDown" Width="20" Height="10"> <Button.Content> <Path Name="ArrowDown" Fill="#404040" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z"/> </Button.Content> </Button> <Button Name="btnUpDown" Width="20" Height="10"> <Button.Content> <Path Name="ArrowDown" Fill="#404040" HorizontalAlignment="Center" VerticalAlignment="Center" Data="{StaticResource IconArrowDown}"/> </Button.Content> </Button> </StackPanel> </Viewbox> ... </UserControl>
Or paint directly to a Canvas
:
<Canvas> <Rectangle Canvas.Left="40" Canvas.Top="31" Width="63" Height="41" Fill="Blue" /> <Ellipse Canvas.Left="130" Canvas.Top="79" Width="58" Height="58" Fill="Blue" /> <Path Canvas.Left="61" Canvas.Top="28" Width="133" Height="98" Fill="Blue" Stretch="Fill" Data="M61,125 L193,28"/> </Canvas>
Polygon
Creating polygons with behavior. In this example, some triangles working as thumbnails:
<Canvas Name="thumbUp" Height="20" Margin="3,0,0,0" Visibility="Collapsed"> <Polygon Name="thumbBinauralUp" Stroke="DarkGray" StrokeThickness="1" Fill="LightGray" HorizontalAlignment="Center" MouseLeftButtonUp="thumbBinauralUp_MouseLeftButtonUp" Points="0,20 20,0 40,20 0,20"> </Polygon> <Polygon Name="thumbRightUp" Stroke="DarkGray" StrokeThickness="1" Fill="{StaticResource SideRightStyle}" HorizontalAlignment="Center" Points="0,20 10,10 20,20 0,20"> </Polygon> <Polygon Name="thumbLeftUp" Stroke="DarkGray" StrokeThickness="1" Fill="{StaticResource SideLeftStyle}" HorizontalAlignment="Center" MouseLeftButtonUp="thumbLeftUp_MouseLeftButtonUp" Points="20,20 30,10 40,20 20,20"> </Polygon> </Canvas>
Supporting C# code:
private void thumbBinauralUp_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { // Do work here MessageBox.Show("Binaural Up"); } private void thumbLeftUp_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { // Do work here MessageBox.Show("Left Up"); }
ProgressBar
ProgressBar
example using dynamic resources:
<ProgressBar Margin="0" VerticalAlignment="Top" Height="20" Style="{DynamicResource SimpleProgressBar}" Value="50" IsIndeterminate="false"> <ProgressBar.Background> <LinearGradientBrush EndPoint="1,0" StartPoint="0,0"> <GradientStop Color="#FFBABABA" Offset="0"/> <GradientStop Color="#FFC7C7C7" Offset="0.5"/> <GradientStop Color="#FF5D9C1D" Offset="0.75"/> </LinearGradientBrush> </ProgressBar.Background> </ProgressBar>
RadioButton
To group several RadioButton
s, make them part of the same group:
<GroupBox Header="Mem Count"> <StackPanel Orientation="Vertical"> <RadioButton Name="btnMem1" GroupName="Mem" Content="1" Click="RadioButton_Click"/> <RadioButton Name="btnMem2" GroupName="Mem" Content="2" Click="RadioButton_Click"/> <RadioButton Name="btnMem3" GroupName="Mem" Content="3" Click="RadioButton_Click"/> <RadioButton Name="btnMem4" GroupName="Mem" Content="4" Click="RadioButton_Click" IsChecked="True" /> </StackPanel> </GroupBox>
To determine which RadioButton
was selected in a group:
private void RadioButton_Click(object sender, RoutedEventArgs e) { if( btnMem1.IsChecked == true) { MessageBox.Show(btnMem1.Content.ToString()); } else if (btnMem2.IsChecked == true) { MessageBox.Show(btnMem2.Content.ToString()); } else if (btnMem3.IsChecked == true) { MessageBox.Show(btnMem3.Content.ToString()); } else { MessageBox.Show(btnMem4.Content.ToString()); } }
Rectangle
A Rectangle
geometric figure:
<Rectangle x:Name="rect" Width="200" Height="100" RadiusY="20" RadiusX="20" StrokeThickness="5"/>
Slider
Slider
example:
<Slider Ticks="1, 2, 3, 4, 5" TickPlacement="BottomRight" Delay="100" Interval="5" Minimum="1" Maximum="5" Value="1" AutoToolTipPlacement="BottomRight" ValueChanged="slider_ValueChanged"> </Slider> <!-- Slider with Range --> <Slider Width="200" HorizontalAlignment="Left" Minimum="0" Maximum="100" Value="90" TickFrequency="10" TickPlacement="BottomRight" IsSelectionRangeEnabled="True" SelectionStart="50" SelectionEnd="100"> </Slider> <!-- Slider with dynamic resource style --> <Slider RenderTransformOrigin="0,0" Margin="3" Name="Slider2" Style="{DynamicResource SimpleSlider}" Height="22" Maximum="100" Minimum="0" Value="0"> <Slider.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="-1" ScaleY="-1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="179.863"/> <TranslateTransform X="-0.954" Y="-9.028"/> </TransformGroup> </Slider.RenderTransform> <Slider.Background> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFFFFFFF" Offset="0"/> <GradientStop Color="#FFF5A544" Offset="1"/> </LinearGradientBrush> </Slider.Background> </Slider>
And some sample code to handle the slider changes:
void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { double value = e.NewValue; ImageBrush imageBrush = this.FindName("imageBrush") as ImageBrush; imageBrush.Viewbox = new Rect(0.3, 0.3, 1 / value, 1 / value); }
References:
TabControl
TabControl
with TabItem
on the right side:
<TabControl TabStripPlacement="Right"> <TabControl.Resources> <Style TargetType="{x:Type TabItem}"> <Setter Property="Padding" Value="4" /> <Setter Property="HeaderTemplate"> <Setter.Value> <DataTemplate> <ContentPresenter Content="{TemplateBinding Content}"> <ContentPresenter.LayoutTransform> <RotateTransform Angle="90" /> </ContentPresenter.LayoutTransform> </ContentPresenter> </DataTemplate> </Setter.Value> </Setter> </Style> </TabControl.Resources> <TabItem Header="Tab Item 1" /> <TabItem Header="Tab Item 2" /> <TabItem Header="Tab Item 3" /> <TabItem Header="Tab Item 4" /> </TabControl>
References
TextBlock
TextBlock
with linebreak:
<TextBlock TextAlignment="Center" FontSize="16" FontFamily="Century Gothic" FontWeight="Bold" Foreground="Navy" FontStyle="Italic" > Hello <LineBreak/> World! </TextBlock>
TextBlock
with space and newline preservation:
<TextBlock TextAlignment="Center" FontSize="16" FontFamily="Century Gothic" FontWeight="Bold" Foreground="Navy" FontStyle="Italic" xml:space="preserve"> Hello World! </TextBlock>
TextBlock
with truncated text showing tooltip displaying full text :
<TextBlock Width="100" TextTrimming="CharacterEllipsis" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Text}"> This is a long sentence with text. </TextBlock>
Alternatively, use a behavior: Customizing "Lookful" WPF controls
TextBox
TextBox
that has auto highlighted text when control gains focus:
<TextBox Name="txtbox" Width="25" Text="Some Value" GotFocus="txtbox_GotFocus"/>
Code to highlight:
///---------------------------------------------------------------------------------------- /// <summary> /// Highlight text in a textbox control when control gains focus. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> ///---------------------------------------------------------------------------------------- private void txtbox_GotFocus(object sender, RoutedEventArgs e) { //textbox.SelectionStart = 0; //textbox.SelectionLength = textbox.Text.Length; ((TextBox)sender).SelectionStart = 0; // Start selection at beginning. ((TextBox)sender).SelectionLength = ((TextBox)sender).Text.Length; // Length of text in Text1. }
TextBox
with a scrollbar:
<TextBox Name="txtBox" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">This is a TextBox</TextBox>
TreeView
<TreeView Name="treeFittingOperations" Grid.Row="1" Margin="5" FontSize="15" BorderThickness="0" Visibility="Hidden" SelectedItemChanged="treeFittingOperations_SelectedItemChanged"> <TreeViewItem Header="Read Instrument"/> <TreeViewItem Header="Initial Fit"/> <TreeViewItem Header="Quick Adjustments"/> <TreeViewItem Header="Fine Adjustments"> <TreeViewItem Header="Gain / Equalizers"/> <TreeViewItem Header="Frequency Cut-off"/> <TreeViewItem Header="Compression"/> <TreeViewItem Header="Expansion"/> <TreeViewItem Header="Advanced"/> <TreeViewItem Header="Adaptive"/> <TreeViewItem Header="Indicators"/> <TreeViewItem Header="Other"/> <TreeViewItem Header="Verification"/> <TreeViewItem Header="Datalog"/> </TreeViewItem> <TreeViewItem Header="Solutions"/> <TreeViewItem Header="Finish"/> </TreeView>
private void treeFittingOperations_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e) { TreeViewItem tviSelected = (TreeViewItem)treeFittingOperations.SelectedItem; // activate relevant parent tabPageControl tab if (tabControlMain != null) { // disable tabs tabPatientContactInfo.Visibility = Visibility.Collapsed; tabPatientAudiologicalData.Visibility = Visibility.Collapsed; tabProducts.Visibility = Visibility.Collapsed; tabFitting.Visibility = Visibility.Collapsed; tabDatalog.Visibility = Visibility.Collapsed; tabReports.Visibility = Visibility.Collapsed; tabFinish.Visibility = Visibility.Collapsed; tabControlMain.Items.Clear(); //MessageBox.Show(tviSelected.Header.ToString()); //debug // activate relevant tab(s) switch (tviSelected.Header.ToString()) { case "Datalog": tabControlMain.Items.Add(tabDatalog); //tabDatalog.Visibility = Visibility.Visible; break; case "Finish": tabControlMain.Items.Add(tabFinish); //tabDatalog.Visibility = Visibility.Visible; break; default: tabControlMain.Items.Add(tabFitting); //tabFitting.Visibility = Visibility.Visible; break; } } // activate relevant child tabPageControl tab switch (tviSelected.Header.ToString()) { case "Read Instrument": MessageBox.Show("Simulation: Instrument was read successfully"); break; case "Autofit": case "Initial Fit": tabControlFitting.SelectedItem = tabAutofits; break; case "Solutions": tabControlFitting.SelectedItem = tabSolutionsGuide; break; case "Quick Adjustments": tabControlFitting.SelectedItem = tabQuickAdjustments; break; case "Fine Adjustments": tabControlFitting.SelectedItem = tabFineAdjustments; break; case "Gain / Equalizers": tabControlFitting.SelectedItem = tabEqualizers; break; case "Frequency Cut-off": tabControlFitting.SelectedItem = tabFitFreqCutOff; break; case "Compression": tabControlFitting.SelectedItem = tabFitCompression; break; case "Expansion": tabControlFitting.SelectedItem = tabFitExpansion; break; case "Advanced": tabControlFitting.SelectedItem = tabFitAdvanced; break; case "Adaptive": tabControlFitting.SelectedItem = tabFitAdaptive; break; case "Indicators": tabControlFitting.SelectedItem = tabFitIndicators; break; case "Other": tabControlFitting.SelectedItem = tabFitOther; break; case "Datalog": //tabControlFitting.SelectedItem = tabDatalog; break; case "In Situ Verification": case "Verification": tabControlFitting.SelectedItem = tabInSituVerification; break; } // Refresh Tabs (call again, otherwise tab selection does not refresh. // Used to work in .NET 3.5, but stopped with .NET 4.0). tabControlFitting.BeginInit(); tabControlFitting.EndInit(); tabControlMain.BeginInit(); tabControlMain.EndInit(); }
Timer
In WPF, Timer
runs on a separate thread from the UI thread, so you need to use DispatcherTimer
instead:
void ActivateTimer() { // using System.Windows.Threading; DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(10); // 10 seconds timer.Tick += new EventHandler(timer_Tick); // Subscribe to Tick event handler timer.Start(); } void timer_Tick(object sender, EventArgs e) { // Do something every tick }
URI
To create a URI
programmatically:
// Absolute URI (default) Uri absoluteUri = new Uri("pack://application:,,,/File.xaml", UriKind.Absolute); // Relative URI Uri relativeUri = new Uri("/File.xaml", UriKind.Relative);
More information: MSDN: Pack URIs in WPF
WebBrowser
A simple WebBrowser
control:
<Grid> <WebBrowser Name="HtmlBrowserReport" /> </Grid>
Clicking a button to load a web page:
private void btnWebsite_Click(object sender, RoutedEventArgs e) { // External Website HtmlBrowserReport.Navigate(new Uri("http://www.example.com", UriKind.RelativeOrAbsolute)); } private void btnViewReport_Click(object sender, RoutedEventArgs e) { // Local web page // NOTE: Use siteoforigin for local files. Only files relative to application folder can be opened // No GET parameters can be passed through URI. // More Reading: http://www.dotnetfunda.com/articles/article840-working-with-webbrowser-in-wpf.aspx //HtmlBrowserReport.Navigate(new Uri("pack://siteoforigin:,,,/htmlpage1.htm", UriKind.RelativeOrAbsolute)); HtmlBrowserReport.Navigate(new Uri("pack://siteoforigin:,,,/reports/report.htm", UriKind.RelativeOrAbsolute)); // located in subdir "reports" }
Execute a JavaScript routine from C#: (see more: Working with WebBrowser in WPF)
public class TSampleApp { // Fields private WebBrowser aWebBrowser; . . . // Constructor public TSampleApp() { aWebBrowser = new WebBrowser(); aWebBrowser.LoadCompleted -= new LoadCompletedEventHandler(aWebBrowser_LoadCompleted); aWebBrowser.LoadCompleted += new LoadCompletedEventHandler(aWebBrowser_LoadCompleted); } public void LoadWebPage(string aWebPage) { // Load a webpage using Source property or Navigate() method // Load an external website aWebBrowser.Navigate("http://www.example.com"); aWebBrowser.Navigate(new Uri("http://www.example.com", UriKind.RelativeOrAbsolute)); // Load a local file aWebBrowser.Navigate("Products/Catalog/prodspec.htm"); aWebBrowser.Source = new Uri(@"pack://siteoforigin:,,,/Products/Catalog/prodspec.htm", UriKind.RelativeOrAbsolute); } void aWebBrowser_LoadCompleted(object sender, NavigationEventArgs e) { // Call JavaScript routine after the document has been loaded completely // Example: //aWebBrowser.InvokeScript("getAlert"); // call javascript function with no params //aWebBrowser.InvokeScript("LoadDoc", new object[] { "prod_Name.pdf" }); // call javascript function with params string AppDir = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName); string ProdSpecPDFFilePath = "file:///" + System.IO.Path.Combine(AppDir, string.Format(@"Products\Catalog\{0}.pdf", _SelectedProduct.Code)).Replace("\\", "\\\\"); aWebBrowser.InvokeScript("LoadDoc", new object[] { ProdSpecPDFFilePath }); } }
Sample HTML page with JavaScript to call:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>This page comes from Stream</title> <script type="text/javascript"> function getAlert() { alert("Hi the page is loaded!!!"); } window.onload = getAlert; function LoadDoc(message){ document.write("Message : " + message); } </script> </head> <body> <input type="text" id="txtMessage" /> </body> </html>
Window
A simple Window
:
<Window x:Class="MyApp.winMain" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyApp" Name="frmMain" Title="MyApp 1.0" Icon="/images/app-icon.ico" Height="600" Width="1024" MinHeight="600" MinWidth="1024" Background="Transparent" MouseLeftButtonDown="frmMain_MouseLeftButtonDown"> <Grid> <!-- Content Goes Here --> </Grid> </Window>
A Window
without border, with custom Maximized, Minimized, Closed, Drag, and Stretch functionality:
<Window x:Class="MyApp.winMain" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyApp" Name="frmMain" Title="MyApp 1.0" Icon="/images/app-icon.ico" Height="600" Width="1024" WindowStyle="None" AllowsTransparency="True" ResizeMode="CanResizeWithGrip" MinHeight="600" MinWidth="1024" Background="Transparent" MouseLeftButtonDown="frmMain_MouseLeftButtonDown"> <Border CornerRadius="20" BorderBrush="SteelBlue" BorderThickness="1" Background="White"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="20"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--Window Controls--> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> <Button Name="btnWinMin" Content="Min" Click="btnWinMin_Click"/> <Button Name="btnWinMax" Content="Max" Click="btnWinMax_Click"/> <Button Name="btnWinClose" Content="X" Click="btnWinClose_Click"/> </StackPanel> <!--Main User Control (or whatever other content required) --> <local:ucMain Grid.Row="0" Grid.RowSpan="2"/> </Grid> </Border> </Window>
/// <summary> /// Interaction logic for winMain.xaml /// </summary> public partial class winMain : Window { public winMain() { InitializeComponent(); } private void frmMain_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // Drag Window (especially if no border is present) this.DragMove(); } private void btnWinMin_Click(object sender, RoutedEventArgs e) { this.WindowState = WindowState.Minimized; } private void btnWinMax_Click(object sender, RoutedEventArgs e) { if (this.WindowState == WindowState.Normal) { this.WindowState = WindowState.Maximized; this.btnWinMax.Content = "Normal"; } else { this.WindowState = WindowState.Normal; this.btnWinMax.Content = "Max"; } } private void btnWinClose_Click(object sender, RoutedEventArgs e) { this.Close(); } }
NOTE: Using AllowsTransparency=“True”
with WindowsFormsHost
control will actually hide the WinForms content inside WindowsFormsHost
. It is a known issue. Basically, it does not paint when set to AllowsTransparency=“True”
.
Dual Monitor Support
Source: Shankar Manne: To Open WPF window in Dual Monitor
Here in this example I created two windows, one is InternalWindow and other is ExternalWindow. My requirement is to open the InternalWindow in First Monitor and ExternalWindow in SecondMonitor, for that go to App.xaml
, remove StartUpUri
and override the following method:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); InternalMain WinInternal = new InternalMain(); ExternalMain WinExternal = new ExternalMain(); Screen s1 = Screen.AllScreens[0]; Rectangle r1 = s1.WorkingArea; WinInternal.Top = r1.Top; WinInternal.Left = r1.Left; if (Screen.AllScreens.Length > 1) { Screen s2 = Screen.AllScreens[1]; Rectangle r2 = s2.WorkingArea; WinExternal.Top = r2.Top; WinExternal.Left = r2.Left; WinExternal.Show(); } else { System.Windows.MessageBox.Show("External Monitor is not connected", "Dual Monitor Error", MessageBoxButton.OK, MessageBoxImage.Error); } WinInternal.Show(); WinExternal.Owner = WinInternal; }
Note: WindowStartupLocation
should not be set to Center