Infragistics ASP.NET controls

XAML Basics: Styles

          Styles in XAML If you are a Microsoft Windows developer, chances are you are using XAML with one of the prominent development technologies (WPF, Windows Phone, SilverLight, WinRT).  XAML is a wonderful markup language that provides a whole new look at developing applications for the Microsoft Windows operating system.  In this series, I plan to cover the basics of XAML as they apply to these technologies.  Microsoft has put a lot behind XAML and I think we know that it has a bright future when it comes to Windows development. What are XAML styles? You can think of a style in XAML much as you would CSS styles in HTML.  Styles provide a way for you to change the visual properties of a given control or set of controls.  Never before has the developer had this much freedom when it comes to changing the appearance of the standard Windows controls.  Using Styles you can declare the font size and family of all buttons in an application.  You can create style resource files that serve as style libraries that can be shared by applications. This article will use WPF as the technology when explaining XAML styles, however, most if not all of the principles can be used with the other XAML based technologies. Defining styles in your application The way that you define styles is very much the same in WPF, SilverLight, and WinRT applications with subtle differences.  You can define styles at the Window, Page, UserControl, Application, and Resource Dictionary levels. We will start with an example of a WPF window called MainWindow.xaml. MainWindow.xaml <Window x:Class="WPF_styles_article_example.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> <StackPanel Orientation="Vertical" > <Button Margin="20" Name="btnOne" Content="Button One" Width="260" Height="40"> </Button> <Button Margin="20" Name="btnTwo" Content="Button two" Width="260" Height="40"> </Button> </StackPanel> </Grid> </Window>   Here's the output As you can see, we have two buttons contained inside of a StackPanel.  They both share the same height and width. You typically want a consistent look for all elements of your application.  If you were to follow the method used in this example, you would need to find each button in the entire application to make any changes to the properties of your buttons.  The more properties that are set on the button, the more potential properties that you would need to change. The XAML style object Styles are defined in a Style object.  A xaml Style contains a collection of Setter objects.  These Setter objects allow you to specify the control type in which the style should be applied, the property of the control to change, and the property value that you wish to set for the specified control type.  Styles are defined in Resource Dictionaries.  Once you've created your Style and populated the setters to define the properties and property values to be applied, you can then reference this resource in the Style property of the control that you wish style.   Here is an example of changing the style of a control by binding a style resource to the control's Style property. <Window x:Class="WPF_styles_article_example.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"> <Window.Resources> <!-- Here we define our Style object and populate it's setter collection with property names and values. Notice that we specify the TargetType as the type of control that can use the style. --> <Style x:Key="CustomButtonStyle" TargetType="Button"> <Setter Property="FontFamily" Value="Verdana" /> <Setter Property="FontSize" Value="30" /> <Setter Property="Width" Value="260" /> <Setter Property="Height" Value="40" /> </Style> </Window.Resources> <Grid> <StackPanel Orientation="Vertical" > <!-- Notice that we have moved all visual property settings into the style resource. --> <Button Margin="20" x:Name="btnOne" Content="Button One" Style="{StaticResource CustomButtonStyle}" /> <Button Margin="20" Name="btnTwo" Content="Button two" Width="260" Height="40" /> <!-- Notice that setting the properties on the Button will override the properties specified in the style. --> <Button Margin="20" Name="btnThree" Content="Button three" Style="{StaticResource CustomButtonStyle}" FontSize="15" FontFamily="Wide Latin" /> </StackPanel> </Grid> </Window> Here's the output As you can see, we've taken the visual properties of btnOne and moved them into a Style resource.  We specify the x:Key property so that the style resource can be referenced by other controls.  We specify the type of control that can use the style by setting the TargetType property and populate the Style's Setter collection with Setter objects that define property names and values of the style. You'll also notice that we added a third button and set it's Style property just as we did with btnOne, however, btnThree overrides the properties that we defined in the Style resource.  Properties set at the control level take precedence over the properties defined in the Style resource. Creating a default style for a specified control type. In the previous example, we defined a Style resource and referenced the resource key in two of the three control's Style properties.  Since we didn't specify the Style property of btnTwo, it was not effected by the Style's defined Setter property values. What happens if we wanted to define a default Style for all of the button's for the current Window?  As it turns out, this process is fairly simple.  All we have to do is remove the Style's x:Key property.  This will cause all of the control's of the specified TargetType to apply the specified style.  Here is an example. <Window x:Class="WPF_styles_article_example.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"> <Window.Resources> <!-- I've removed the x:Key attribute to apply the style to all Buttons in the window. --> <Style TargetType="Button"> <Setter Property="FontFamily" Value="Verdana" /> <Setter Property="FontSize" Value="30" /> <Setter Property="Width" Value="260" /> <Setter Property="Height" Value="40" /> </Style> </Window.Resources> <Grid> <StackPanel Orientation="Vertical" > <!-- No styles set --> <Button Margin="20" x:Name="btnOne" Content="Button One" /> <Button Margin="20" Name="btnTwo" Content="Button two" /> <Button Margin="20" Name="btnThree" Content="Button three" /> </StackPanel> </Grid> </Window> Here's the output Applying styles across an entire application The previous examples demonstrate defining the Style resources at the Window level.  The same approach applies to Pages and UserControls. If you want to make styles available to the entire application, simply create an Application level resource.   Here is an example. <Application x:Class="WPF_styles_article_example.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <Style TargetType="Button"> <Setter Property="FontFamily" Value="Verdana" /> <Setter Property="FontSize" Value="30" /> <Setter Property="Width" Value="260" /> <Setter Property="Height" Value="40" /> </Style> </Application.Resources> </Application> Here's the output Conclusion This concludes the first article in the XAML basics series.  The next article in the series will build on the concept of XAML styles by introducing Control Templates. Stay tuned! kick it on DotNetKicks.com   


C# 5.0: INotifyPropertyChanged with the [CallerMemberName] attribute

WPF/Silverlight and the INotifyPropertyChanged interface Greetings and welcome to another post on refactorthis.net. Today's topic is about an interface that all WPF and Silverlight developers have grown to love.  The INotifyPropertyChanged interface facilitates notifying the data binding mechanisms of WPF and Silverlight of a property value change in your ViewModel to your view.  Here is a simple illustration.   ClassicViewModel.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace INotifyPropertyChangedExample { public class ClassicViewModel { private string _personName; public event PropertyChangedEventHandler PropertyChanged; public string PersonName { get; set { if (value != _personName) _personName = value; //No type safety here. If you make a mistake you will have problems. OnPropertyChanged("PersonName"); } } public void OnPropertyChanged(string property) { if (property == null) throw new ArgumentNullException("property"); if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property)); } } } When calling the method to raise the property changed event, you would need to pass the property name as a string to the handler.  If you made any mistake in typing the property name, you would have to take time to debug your data binding. A new and improved solution C# 5.0 has provided some nifty compiler level attributes to assist with this scenario. The [CallerMemberName] attribute of the System.Runtime.CompilerServices namespace can be used as an optional method parameter.  When a method is called and there is no value specified for the parameter that is decorated with this attribute, you are provided with the name of the member that called the method.  This takes the risk of a typing mishap out of your hands and allows you to rely on the compiler to provide this information to you!  Here is an updated example! ImprovedViewModel.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace INotifyPropertyChangedExample { public class ImprovedViewModel : INotifyPropertyChanged { private string _personName; public event PropertyChangedEventHandler PropertyChanged; public string PersonName { get { return _personName; } set { if (value != _personName) _personName = value; OnPropertyChanged(); } } public void OnPropertyChanged([CallerMemberName] string property = null) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property)); } } }   As you can see, this is a great little addition to the C# language that will make your life a little easier. I'd like to thank Patrick Steel for his article in MSDN magazine that inspired this article.  Please check out his article for more uses of this and other new attributes and features of the C# 5.0 language. http://visualstudiomagazine.com/Articles/2012/11/01/More-Than-Just-Async.aspx kick it on DotNetKicks.com


Implementing a re-sizable composite view user interface using the MVVM pattern, the GridSplitter, and WPF UserControls.

  A composite view user interface In the world of WPF, the Model-View-ViewModel pattern is a great way to separate your UI from your business logic.  This decoupling allows you to easily unit test your code.  When implemented correctly, the MVVM pattern promotes a view agnostic structure which makes switching between different views extremely easy.  A composite view UI is basically a user interface that is made up of multiple independent views.  By independent, I mean that the views should be decoupled and unaware of each other.  In this tutorial, I will show you how to create the following UI.     Existing frameworks There are several existing frameworks that facilitate the implementation of the MVVM pattern and composite view applications.  MVVM Toolkit, MvvMLight, SoPrism, and Prism are a few examples of some of the existing libraries out there.  Prism is probably the most complete and extensive but it also has a large learning curve.  I decided that before I dive into learning the details of Prism, I would benefit by trying to code a composite application by hand.  The User Interface design The previous screen shot shows an application made up of a Window that contains a grid, a listview, and a ContentControl.  The ContentControl and ListView are separated by a GridSplitter control.  This allows the two views to be re-sized.  The ContentControl will have a UserControl injected into the content property as the ListView's selected item is changed. Here is the XAML markup <Window x:Class="OutlookLayoutPresenter.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:views="clr-namespace:OutlookLayoutPresenter.Views" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="128*" /> <ColumnDefinition Width="375*" /> </Grid.ColumnDefinitions> <ListView SelectionChanged="lstMenu_SelectionChanged" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="MenuDisplayText" x:Name="lstMenu"> </ListView> <ContentControl Grid.Column="1" Content="{Binding Path=Presenter.CurrentView}" x:Name="MainContent"> </ContentControl> <GridSplitter Grid.Column="1" Width="2" HorizontalAlignment="Left" /> </Grid> </Window> As you can see, we have a Grid with two columns.  The column on the left holds a ListView that that is data bound in the code behind.  The ContentControl's content property is also data bound to the Presenter.CurrentView property of our ViewModel.  I chose to implement a presenter object to handle the injection of the UserControl into the ContentControl.  We will start with the codebehind of our view to show how we are setting the DataContext. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using OutlookLayoutPresenter.Views; namespace OutlookLayoutPresenter { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private MainWindowViewModel _viewModel; public MainWindow() { InitializeComponent(); _viewModel = new MainWindowViewModel(); this.DataContext = _viewModel; lstMenu.ItemsSource = _viewModel; } void lstMenu_SelectionChanged(object sender, SelectionChangedEventArgs e) { var menuItem = (ViewMenuItems)e.AddedItems[0]; _viewModel.Presenter.DisplayView(menuItem); } } } Note that we have bound our ViewModel to the view's DataContext as well as the ListView's ItemsSource property.  The ViewModel is an ObservableCollection of ViewMenuItem objects.  I created the ViewMenuItem class to contain the region's name and the display text.  The ListView serves as a menu.   Here is the code for the ViewMenuItem class. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace OutlookLayoutPresenter { public class ViewMenuItems : INotifyPropertyChanged { private string _regionName; private string _menuDisplayText; public string RegionName { get { return _regionName; } set { if (_regionName == value) return; _regionName = value; OnPropertyChanged("RegionName"); } } public string MenuDisplayText { get { return _menuDisplayText; } set { if (_menuDisplayText == value) return; _menuDisplayText = value; OnPropertyChanged("MenuDisplayText"); } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } } When looking at the ViewModel, please be sure to note the public Presenter property that is used in the data binding of the ContentControl. The ObservableCollection of ViewMenuItem objects builds the ListView menu. Here's the ViewModel's code using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Collections.ObjectModel; namespace OutlookLayoutPresenter { public class MainWindowViewModel : ObservableCollection<ViewMenuItems> , INotifyPropertyChanged { private IPresenter _presenter; public IPresenter Presenter { get { return _presenter; } set { _presenter = value; OnPropertyChanged("Presenter"); } } public MainWindowViewModel () { this.Add(new ViewMenuItems{RegionName = "RegionOne", MenuDisplayText = "Content One"}); this.Add(new ViewMenuItems{RegionName = "RegionTwo", MenuDisplayText = "Content Two"}); this.Add(new ViewMenuItems{RegionName = "RegionThree", MenuDisplayText = "Content Three"}); this.Presenter = new MainWindowPresenter(); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } } All that's left now is the MainWindowPresenter class which will dynamically load one of three user controls based on the ListView's selected item. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Windows.Controls; using OutlookLayoutPresenter.Views; namespace OutlookLayoutPresenter { /// <summary> /// This is the presenter class for the main Shell. the purpose of this /// class is to contain all of the UI event handlers for the main shell view. /// </summary> public class MainWindowPresenter : INotifyPropertyChanged, IPresenter { ContentControl _currentView = new ContentControl(); public ContentControl CurrentView { get { return _currentView; } set { _currentView = value; OnPropertyChanged("CurrentView"); } } public void DisplayView(ViewMenuItems item) { switch (item.RegionName.ToUpper()) { case "REGIONONE": this.CurrentView.Content = new ContentOne(); break; case"REGIONTWO": this.CurrentView.Content = new ContentTwo(); break; case "REGIONTHREE": this.CurrentView.Content = new ContentThree(); break; } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } } } There are three user controls that have a different background color and text.  I will show the markup for one of the controls for brevity. <UserControl x:Class="OutlookLayoutPresenter.Views.ContentOne" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" Background="Blue"> <Grid> <TextBlock FontWeight="Bold" Foreground="White" Text="Content One" /> </Grid> </UserControl>   As you click on each menu item, the content view will change colors and text.  I've included the source code for your reference. OutlookLayoutPresenterMVVM.zip (93.27 kb)   This concludes the tutorial.  Thanks for reading! Until next time... Buddy James kick it on DotNetKicks.com      


WPF Snoop: A must have tool for WPF development.

WPF Snoop: A WPF developers dream WPF is the latest development methodology for developing Windows Desktop applications.  If you come from a WinForms background, there is a considerably steep learning curve that comes along with WPF.  This is in part due to the nature of the XAML declarative markup.  You can instantiate objects,  execute data binding and many other complex tasks all without touching a line of c#.  Couple this with the new flow style layout of WPF user interfaces, there's plenty for a new developer to learn.  While surfing online I ran across an open source tool on codeplex that greatly reduces some of the complexities of developing in WPF. WPF Snoop and what it can do for you Imagine you've downloaded an example WPF application with the best user interface you've ever seen.  You are new to WPF, so despite your best efforts, you can't quite grasp how the UI is tied together.  What if you had an application that allowed you to attach to the application and  allowed you to view the visual tree of the application's user interface?  Imagine viewing each and every control, and property in the entire UI. Better yet, imagine the ability to change the properties of the UI controls on the fly?   WPF snoop also makes debugging WPF data binding a breeze!  You can select a data bound ListView and view as well as modify the ItemsSource.  WPF Snoop can achieve all of this and more! Here's a quick tutorial.. Download WPF snoop To begin, download WPF snoop from the following URL http://snoopwpf.codeplex.com/ Once installed, launch the application.  The application toolbar looks like this.     Next, launch the application that you wish to snoop.  I'm going to use a school course editor example that I found on the codeproject. I then click the crosshair and drag it over the application that I wish to snoop. I'm then presented with a dialog that contains the visual tree and all of the properties of the controls.   As I drill down into the visual tree, I can hover over each node and it will display a thumbnail of the contents of that node.  Once I've reached a part of the UI that I wish to isolate, I can click on the node and this will actually draw a red border around the area in the application.  Here is a screen shot for your reference.     Also notice the tabbed interface.  When you click on the DataContext tab, you can view all of the relevant data binding information.  Keep in mind that all of the properties can be changed on the fly. The possibilities are endless.   This concludes my tutorial on WPF snoop.  I suggest you download it and start snooping around. This tool will help beginners and newbies alike.   Until next time!  Cheers! ~/Buddy James kick it on DotNetKicks.com


About the author

My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

Related links

Month List