How can I create a custom WPF button whose look and feel depends on the Windows desktop theme currently in use. How do I get notified when the user changes the theme?
The WPF theme engine will switch styles automatically for you if you place them in separate ’ResourceDictionary’ XAML files compiled in your application. The files need to be named. themes\..xaml For example, these are the themes that Microsoft produces. themes\luna.normalcolor.xaml themes\luna.homestead.xaml themes\luna.metallic.xaml themes\royale.normalcolor.xaml themes\aero.normalcolor.xaml The case for classic is slightly different. themes\classic.xaml Windows Presentation Foundation does not provide an event to notify the user regarding theme changes. If you need to go beyond what is provided by styles in a ResourceDictionary, you will need to listen to the ’WM_THEMECHANGE’ message in a window hook.
How can I set a ControlTemplate in the style template?
The ControlTemplate specifies the appearance of a Control. If a Control does not have a ControlTemplate, the Control will not appear in your application. The control author defines the default control template and the application author can override the ControlTemplate to redefine the visual tree of the control. A ControlTemplate is intended to be a self-contained unit of implementation detail that is invisible to outside users and objects, including Style objects. The content of the ControlTemplate can be manipulated within the same ControlTemplate only. The following example creates a ControlTemplate for a Button. If you add this to your application as a resource, all the buttons in the application will appear as ellipses but will still function as buttons. [XAML] <Style TargetType=’Button’> <!–Set to true to not get any properties from the themes.–> <Setter Property=’OverridesDefaultStyle’ Value=’True’/> <Setter Property=’Template’> <Setter.Value> <ControlTemplate TargetType=’Button’> <Grid> <Ellipse Fill='{TemplateBinding Background}’/> <ContentPresenter HorizontalAlignment=’Center’ VerticalAlignment=’Center’/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
How do I prevent a control from being resized manually by the user or through docking or anchoring?
The best way to ensure a particular height or width for a control is to override the control’s SetBoundsCore method. This sample shows a Button which has a fixed height and width. The same technique can be used to set the upper and lower bounds on sizes. [C#] using System.Windows.Forms; public class ButtonWithConstrainedSize : Button { private static int fixedHeight = 50; private static int fixedWidth = 50; protected override void SetBoundsCore( int x, int y, int width, int height, BoundsSpecified specified ) { base.SetBoundsCore( x, y, fixedWidth, fixedHeight, specified ); } }
How do SuspendLayout and ResumeLayout work ?
SuspendLayout and ResumeLayout only prevent ’OnLayout’ from being called. Additionally they only prevent OnLayout from being called for that particular control. So if you have a Form with a Panel in it and call SuspendLayout on the Form, the Panel’s layout will not be suspended. [C#] private void button1_Click(object sender, EventArgs e) { this.Layout += new LayoutEventHandler(Form1_Layout); panel1.Layout += new LayoutEventHandler(Panel1_Layout); // Test one – calling PerformLayout here does not call Form1_Layout. this.SuspendLayout(); this.PerformLayout(); this.ResumeLayout(false); // Test two – calling PerformLayout here calls Panel1_Layout. // Child controls are not suspended when the parent is suspended. this.SuspendLayout(); panel1.PerformLayout(); this.ResumeLayout(false); // Test three, properly suspending layout. this.SuspendLayout(); panel1.SuspendLayout(); panel1.PerformLayout(); // <— Layout event on Panel NOT called panel1.ResumeLayout(false); this.ResumeLayout(false); panel1.Layout -= new LayoutEventHandler(Panel1_Layout); this.Layout -= new LayoutEventHandler(Form1_Layout); }
How can I obtain a writable copy of a Read-Only Freezable?
This example shows how to use the Clone method to create a writable copy of a read-only Freezable. After a Freezable object is marked as read-only (‘frozen’), you cannot modify it. However, you can use the ’Clone’ method to create a modifiable clone of the frozen object. The following example creates a modifiable clone of a frozen ’SolidColorBrush’ object. [C#] Button myButton = new Button(); SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow); [C#] // Freezing a Freezable before it provides // performance improvements if you don’t // intend on modifying it. if (myBrush.CanFreeze) { // Makes the brush unmodifiable. myBrush.Freeze(); } myButton.Background = myBrush; // If you need to modify a frozen brush, // the Clone method can be used to // create a modifiable copy. SolidColorBrush myBrushClone = myBrush.Clone(); // Changing myBrushClone does not change // the color of myButton, because its // background is still set by myBrush. myBrushClone.Color = Colors.Red; // Replacing myBrush with myBrushClone // makes the button change to red. myButton.Background = myBrushClone;