Content tagged with wpf
WPF Dockpanel
The dock panel allows you to dock elements on the window in any direction, either top, bottom, left or right. This is useful when you want to divide the window or screen into specific areas with different functionality. It's also useful because the last element will take the whole remaining space in the center, unless this is disabled in the markup code.
The dock elements in the windows, you need to use the DockPanel.Dock element in the controls that you want to anchor. These controls must be declared inside the Dock element to take advantage of this feature. The DockPanel.Dock attribute takes the value of the position you want the control anchored. Below you can find a XAML markup example:
As you can see, we don't need to indicate the dock position of the last element because it'll automatically centers and takes the rest of the space. Another thing to keep in mind is that the controls only take the space that they need. The rest of the space is taken by the center.
You can also observe that some of the controls take more space than the others. For example, the Top button takes the whole width and also the Bottom one. But the Left and Right they just take the height between the Top and the Bottom. This is because of the order in which the controls were added in the dock panel.
Disabling the last child fill
As we mentioned earlier, the last control takes the whole space left in the center. If you want to disable this, just set the LastChildFill property to false and the control won't take the whole space. Below you can see an example:
WPF TabControl Styling
Adding style to the WPF TabControl isn't to difficult. The default style for tabs are pretty generic so you might want to add some styling so the interface looks nice. You can change the borders for the tabs, the background color, the margins and where you want the text for header to go.
Below you can find sample in XAML code
As you can see, we're simply adding a Style element to the tab control setting it's target to the TabItem. We then do a ControlTemplate and set the necessary style elements we want it to have. We're also setting some Triggers that will happen for example when the user clicks on the tab. In the this case, we're changing the BackGround property
WPF TabControl
The WPF tabcontrol allows you to divide information to the user in a single screen. Each tab you configure have different set of controls and content that it's used to present or gather feedback from the application user.
Below you can a simple example in XAML on how to use the tab control with three tabs:
In this sample, the tab control has three tabs defined. The tabs are declared using the TabItem mark up in XAML. This element has property called Header that we can use to name the tabs in the user interface. Inside the TabItem element we inject any content that we need. In this example, I'm creating a Label in the first tab, but you can add as many other elements as you need.
Changing the headers
Because the headers can also have content, you can customize it with other element or control that you wish. In the sample below, we'll add some circles before the labels to give it some colors:
There's a lot mark up in this example, but we're just basically customizing the Header property by adding a TabItem.Header element and then adding a StackPanel inside it. We need the StackPanel to be able to add multiple elements inside the property. Then we add an Ellipse which will draw a circle next to our header text. The header text is defined by the TextBlock element. We can also style the TextBlock however we want (bold, italics, color, etc.)
TabControl Events
Getting the selected can be done using the SelectedItem property and casting it into a TabItem. You can see an example below:
var tabItem =TabControl.SelectItem as TabItem; var header = tabItem.Header;
WPF Margin
The margin property in WPF allows you set spacing between elements in a window. You can assign the margins for the Top, Right, Bottom and Left.
Every control that derives from FrameworkElement has this property.
A simple mark up XAML code with margins is:
It'll render something like this:
Margin in code
The margin property is of type Thickness so you should be able to set margins in code using the following snippet:
buttonTest.Margin = new Thickness(0, 120, 9, 213);
WPF ListView Sorting
If you need to apply sorting to a ListView, this can be done easily. We just need to handle the GridViewColumnHeader.Click on the ListView. Below you can find the XAML code for doing this:
And the C# code to handle the click event:
namespace WpfApplication2 { ////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { GridViewColumnHeader _lastHeaderClicked = null; ListSortDirection _lastDirection = ListSortDirection.Ascending; public MainWindow() { InitializeComponent(); ObservableCollectionbusinesses = new ObservableCollection (); businesses.Add(new Business("Microsoft", "http://www.microsoft.com", "123-421-1231")); businesses.Add(new Business("SkyXoft", "http://www.skyxoft.com", "123-321-1231")); businesses.Add(new Business("LicenseSpot", "http://www.licensespot.com", "123-312-3212")); BusinessListView.ItemsSource = businesses; } private void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e) { GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader; ListSortDirection direction; if (headerClicked != null) { if (headerClicked.Role != GridViewColumnHeaderRole.Padding) { if (headerClicked != _lastHeaderClicked) { direction = ListSortDirection.Ascending; } else { if (_lastDirection == ListSortDirection.Ascending) { direction = ListSortDirection.Descending; } else { direction = ListSortDirection.Ascending; } } string header = headerClicked.Column.Header as string; Sort(header, direction); _lastHeaderClicked = headerClicked; _lastDirection = direction; } } } private void Sort(string sortBy, ListSortDirection direction) { ICollectionView dataView = CollectionViewSource.GetDefaultView(BusinessListView.ItemsSource); dataView.SortDescriptions.Clear(); SortDescription sd = new SortDescription(sortBy, direction); dataView.SortDescriptions.Add(sd); dataView.Refresh(); } } public class Business { public string Company { get; set; } public string Url { get; set; } public string Phone { get; set; } public Business(string company, string url, string phone) { this.Company = company; this.Url = url; this.Phone = phone; } } }
In the code above we are creating three records in the List and binding it to the ListView. This is the simple and straightforward part.
The difference here is the click event. First we determine what header was clicked and we save that information on the headerClicked variable. Then we checked with a class variable what was the last header clicked. If it is different from the one we just clicked, the the grid is just sorted in ascending mode by default. If it's the same header, then we determine what was the last direction it was clicked and select whether to sort ascending or descending.
At the end we have the Sort method. This will actually get a default view from the ListView ItemsSource. This view has the functionality to sort the rows. We just need create a SortDescription object with the parameters about the header clicked and the direction and call the Refresh method. This will do the trick.
WPF ListView Binding
Binding in the ListView will allow you to get information from a database or a list and bind that information to controls. This way, you don't need to manually insert the data into the controls, the ListView will do this automatically.
Below you can an example in XAML on how to use binding:
What we have here is a ListView showing information as a gird. Each column in the grid is bind to a property and this is done using the DisplayMemberBinding attribute. This is indicating to which property in the dataset or object the column maps to.
Binding multiple columns
Binding to multiple columns in the ListView is also pretty straightforward. In the previous XAML sample we're actually binding to more than one column. By adding the C# code below, we can populate this ListView:
namespace WpfApplication2 { ////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Listbusinesses = new List (); businesses.Add(new Business("Microsoft", "http://www.microsoft.com", "123-421-1231")); businesses.Add(new Business("SkyXoft", "http://www.skyxoft.com","123-321-1231")); businesses.Add(new Business("LicenseSpot", "http://www.licensespot.com", "123-312-3212")); BusinessListView.ItemsSource = businesses; } } public class Business { public string Company { get; set; } public string Url { get; set; } public string Phone { get; set; } public Business(string company, string url, string phone) { this.Company = company; this.Url = url; this.Phone = phone; } } }
What we're doing is create a List of Business objects and filling with information. Each Business object has a Company, Url and Phone property that maps to the bindings defined in the XAML markup. When we assign it to the ItemsSource property in the ListView, it'll be automatically filled:
Binding and SelectedItems
For getting the selected items in the ListView when using binding, we simply need to use the SelectedItems property of the ListView and loop through it. The following code shows an example:
foreach (Business business in BusinessListView.SelectedItems) { MessageBox.Show(business.Company); }
Notice that when we do the for each, the SelectedItems actually holds the objects binded to the ListView, so a cast is automatically done and we can interact with the object right away.
Binding and ObservableCollection
Binding to an ObjservableCollection is also pretty straightforward. In the sample below we're changing the value of the Company propety for the first item in the List. When we run the project, you can see that the value is changed on the ListView and we didn't have to rebind it or do any more coding:
namespace WpfApplication2 { ////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ObservableCollectionbusinesses = new ObservableCollection (); businesses.Add(new Business("Microsoft", "http://www.microsoft.com", "123-421-1231")); businesses.Add(new Business("SkyXoft", "http://www.skyxoft.com","123-321-1231")); businesses.Add(new Business("LicenseSpot", "http://www.licensespot.com", "123-312-3212")); BusinessListView.ItemsSource = businesses; businesses[0].Company = "Microsoft Corp"; } } public class Business { public string Company { get; set; } public string Url { get; set; } public string Phone { get; set; } public Business(string company, string url, string phone) { this.Company = company; this.Url = url; this.Phone = phone; } } }
WPF ListView Grouping
Another feature that we have with the ListView is grouping. This will allow you to group rows depending on a specific field. This feature can be customized as needed and give your application extreme usefulness visualizing information.
Below you can see a sample with the XAML and the C# code:
namespace WpfApplication2 { ////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Listbusinesses = new List (); businesses.Add(new Business("Microsoft", "http://www.microsoft.com", "123-421-1231","Enterprise")); businesses.Add(new Business("SkyXoft", "http://www.skyxoft.com","123-321-1231","SMB")); businesses.Add(new Business("LicenseSpot", "http://www.licensespot.com", "123-312-3212","SMB")); BusinessListView.ItemsSource = businesses; CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(BusinessListView.ItemsSource); PropertyGroupDescription groupDescription = new PropertyGroupDescription("Size"); view.GroupDescriptions.Add(groupDescription); } } public class Business { public string Company { get; set; } public string Url { get; set; } public string Phone { get; set; } public string Size { get; set; } public Business(string company, string url, string phone, string size) { this.Company = company; this.Url = url; this.Phone = phone; this.Size = size; } } }
In this sample we've taken the list of businesses and grouping them based on the size of the company. In the XAML we've just added a GroupStyle to the list view in which a template is defined. This template includes a TextBlock that holds the information for the grouping. It has a different style, a bold, to note the difference. The text property is bound to the Name field but it has nothing to do with the Business object. This Name property holds the name of the group as assigned by WPF.
In the C# code we're just adding the objects to a List but we're also using the CollectionView object which has the ability to group items. We do so by creating a PropertyGroupDescription object and adding it as a GroupDescription in the CollectionView. This tells WPF to group the items using the specified property.
Add an expander to the group header
In the previous example, we showed how to group the rows in the ListView. But one common request from end users is to have the ability to expand and collapse the group headers so they can filter the information they see in the screen. In WPF in can't do this by default but we can some templates to do it.
Below you can find the XAML code:
There's no need to modify the C# code, we can use the same one. In the XAML code we're just adding the Expander property and setting it to true to show it the ListView. As you can see in the screenshot, we can now group by the size of the company. We also added the number of items inside the group using the ItemCount property which is also available in the group.
With this, you can quickly style the group to your own requirements and build grid interfaces that really provides added value to your users.
WPF ListView with GridView
In this article we'll talk about using the ListView but with one of it's most useful feature: the GridView. With this functionality we're able to present data to users in the form of tables and rows, just like a data grid would do in the old Windows Forms space.
Below you can find a pretty simple example of a list view with three columns:
namespace WpfApplication2 { ////// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Listbusinesses = new List (); businesses.Add(new Business("Microsoft", "http://www.microsoft.com", "123-421-1231")); businesses.Add(new Business("SkyXoft", "http://www.skyxoft.com","123-321-1231")); businesses.Add(new Business("LicenseSpot", "http://www.licensespot.com", "123-312-3212")); BusinessListView.ItemsSource = businesses; } } public class Business { public string Company { get; set; } public string Url { get; set; } public string Phone { get; set; } public Business(string company, string url, string phone) { this.Company = company; this.Url = url; this.Phone = phone; } } }
In this sample, we have a ListView with three simple columns. We're just changing the default View for the list view to be GridView (this is the only one available but you can create your own). We then just define the columns using the XAML markup as shown above. In each column we're defining the Header that's shown at the top of the grid, the width and the DisplayMemberBinding that binds the value of the column to the actual object we're using in the C# code.
Using templates as cell content
We can add our own controls to grid view columns using the CellTemplate property in WPF. This give us the option to render the content of the columns in any way that we need instead of just displaying strings as the DisplayMemberBinding property does.
In the sample below, we'll be changing the url column to display what an actual link looks like by using the TextBlock element:
As you can see, this very simple. In the middle columns we just specified that we wanted a CellTemplate to be used, define what we wanted as a template (in this case a TextBlock) and just let the control know how to bind to the property. You can use this same approach to basically use any other element as a CheckBox for example as shown in the ListView checkbox sample.
WPF ListView with CheckBox
In this article we'll talk about how to render check boxes inside a ListView. You can use this feature for example, for presenting a list of options to ends users and allowing them to select one option or multiple options. The way you do this is by using DataTemplates inside the ListView and then do some basic data binding to show the controls. In the sample below I've also added functionality to hide the headers for the ListView. The final product we'll essentially look like this:
Adding check boxes to the ListView
To add the check box to each list view item, we need to change the XAML generated for the list and include and add a GridView and will contain two columns: one for the check box and one for the label. Below you can see the XAML code for this, specifically inside the
Hiding the column headers For hiding the headers we just need to style the GridView header and set the Visiblity property to Collapsed as shown in the XAML below:
Binding the check boxes to the ListView
For the binding, I created a class that has two properties: Text and IsChecked. These properties hold the values to the two columns our ListView has. Text will have the actual label to show in the second column and IsChecked determines if the checkbox is checked. It actually represents the object for each row in the list view. It's also implementing the INotifyPropertyChanged that will allow the ListView to update itself when a value in the object changes. You can see the code below:
public class CheckBoxListViewItem : INotifyPropertyChanged { private bool isChecked; private string text; public bool IsChecked { get { return isChecked; } set { if (isChecked == value) return; isChecked = value; RaisePropertyChanged("IsChecked"); } } public String Text { get { return text; } set { if (text == value) return; text = value; RaisePropertyChanged("Text"); } } public CheckBoxListViewItem(string t, bool c) { this.Text = t; this.IsChecked = c; } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propName) { PropertyChangedEventHandler eh = PropertyChanged; if (eh != null) { eh(this, new PropertyChangedEventArgs(propName)); } } }
Now we'll just create some test objects when the Window is created for testing:
ObservableCollectionitems = new ObservableCollection (); items.Add(new CheckBoxListViewItem("Red",false)); items.Add(new CheckBoxListViewItem("Green", true)); items.Add(new CheckBoxListViewItem("Blue", false)); myListView.ItemsSource = items;
This gives you the result below:
Check all button for the ListView
Adding a Check All button is also pretty simple. On click event for the button we just need to loop through the check boxes change the IsChecked property to true. This will automatically notify the ListView and update itself. Below you can see the code:
private void CheckAllButton_Click(object sender, RoutedEventArgs e) { foreach (CheckBoxListViewItem o in myListView.ItemsSource) { o.IsChecked = true; } }
WPF ListView
The ListView is a control that allows you present data to the user using different layouts. The most common one is showing a table with columns with the information. The ListView inherits from ListBox and in WPF provides a number of features that give it a great deal of extensibility being one of them to present information in different formats. Information or data in the ListView is contained within objects. The most basic one is the ListViewItem object that simply represents and item with a single column ListView.
ListView example
Here’s the code of a ListView sample that contains three basic items in the ListViewItem object:
As you can see, we’re able to create it using simple XAML markup giving us the advantage to shape the information as we wanted using WPF functionality. In the code below we have the same list but with the items in bold and italics: