1. Introduction
2. Concept
- XAML
- Layout
- Logical tree
- Visual Tree
3. WPF: How XAML designer loads binaries and how to keep it working
4. Data binding
- One way binding
- Two way binding
- Data template
- Data binding to a collection
- Master-Detail View
- Default values
- Showing and writing null values
- Referencing binding source
- Manipaulate binding in code
- Rasing an event with compiler check
5. Data triggers
- Simple data trigger
- Animation
6. Convertors
- Standard Convertors
- Custom Convertors
7. Application start
8. Dependency properties
- Dependency properties - example
9. Inheritence
10. Static and Dynamic resources
11. Commands
- WinForms style
- Routed commands
- Custom command
- Delegate command - PRISM
- Telerik DelegateCommand
12. Controls
- Grid
- GridSplitter
- Label vs. TexBlock
- ComboBox
- Button - Disable/Enable
- Scrollable TextBox for a large text
- User control
13. Moving from WinForms
- Objects names
- Visibility
- Width vs. ActualWidth
- Commands
- Anchors
- DoEvents()
- Control focus
14. Telerik WPF UI
- Commands
- GridView
1. Introduction
WPF is architected with MVVM (Model-View-ViewModel) pattern, which is an approach that allows to isolate functionality and presentation. You can find comprehensive description on MSDN
Good practical information can be found on:
wpftutorial.net
wpf-tutorial.com
wpfdoc.com
wpfmentor.com
joshsmithonwpf
Following apps can help to explore binding or Logical and Visual trees in a WPF:
WPF Inspectcor
SnoopWpf
2. Concept
XAML
C# partial class Form1 { private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(32, 272); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(100, 22); this.textBox1.TabIndex = 2; } private System.Windows.Forms.TextBox textBox1; }
Those who are familiar with Delphi know that each form has a definition file that does not contain code, but declaration of elements with properties like position, width, heigth, title etc. This is called declarative definition.
WPF introduces annother format for declarative definition, XAML.
XAML <Window x:Class="Fundamentals.Binding.DataContext.PersonsWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="PersonsWindow" Height="300" Width="300"> <Grid> <TextBox Text="Hello" Height="23" Width="120" /> </Grid> </Window>There is still C# code behind in .xaml.cs file
C# namespace Fundamentals.Binding.DataContext { public partial class PersonsWindow : Window { public PersonsWindow() { InitializeComponent(); } } }Visual Studio designer supports design with XAML only.
Layout
Grid - Grid with row and colums, similar HTML table StackPanel - Like grid without columns when Orientation=Vertical. When Orientation=Horizontal - only columns, no rows. WrapPanel - Like StackPanel, but if controls cannot be fit into the width of the panel, new row will be created. Canvas - XY coordinates DockPanel - allows component docking TabPanel - container for multiple tabs
Logical tree
XAML <Window> <StackPanel> <Button Content="Click on me" /> </StackPanel> </Window>
- Resolves Static and Dynamic resources
The same can be achieved by using Children property of FrameworkElement class or calling FindName().
Visual Tree
VisualTreeHelper provides methods that can be used to:
- examine Visaul Tree like GetParent() or GetChild()
- provide information regarding graphical appearace like GetOPacity(), GetTransform() etc. The differences can be visualy exploed by using the tools described aboe
3. WPF: How XAML designer loads binaries and how to keep it working
It may cause a problem if a class used in the visual control loads data from an external file and the file is not available. It such case, in order to allow the designer to work, it is necessary that the code loading e.g. data from an external file does not throw exception, but rather returns empty result.
4. Data binding
You can download code examples that demonstrate:
- one way binding
- two way binding
- data template
- collections
- master-detail view
One way binding
C# class Person { public string PName { get; set; } public string PHeight{ get; set; } }View
XAML
<Window x:Class="Fundamentals.Binding.DataContext.PersonsWindow"
... >
<Grid>
<TextBox Text="{Binding PName}" Margin="12,20,0,0" />
<TextBox Text="{Binding PHeight}" Name="textBox2" />
</Grid>
</Window>
ViewModel
C# public partial class PersonsWindow : Window { private Person _dataSource; public PersonsWindow() { _dataSource = new Person(); _dataSource.PName = "Zbynek"; _dataSource.PHeight = "190"; DataContext = _dataSource; InitializeComponent(); } }
Two way binding
With one way binding, when the data in the model got updated, the change was not visible in the view. In order to achieve that, it is ncecessary to setup 2 was binding. It requires the model to implement INotifyPropertyChanged interface in the model.
Model
C# class Person : INotifyPropertyChanged { public string PName { get; set; } private double _pHeight; public double PHeight { get { return _pHeight; } set { if (value != _pHeight) { _pHeight = value; PropertyChanged(this, new PropertyChangedEventArgs("PHeight")); } } } public event PropertyChangedEventHandler PropertyChanged = delegate { }; }View and ViewModel remain the same as for 1 way binding.
When user changes the datacontext value like ViewModel
C# public partial class PersonsWindow : Window { ... private void btnIncrement_Click(object sender, RoutedEventArgs e) { ((Person)this.DataContext).PHeight += 1; } }With 2 way binding the value in UI will be updated when it gets changed in the model.
Data template
XAML <Window x:Class="Fundamentals.Binding.DataContext_Template.PersonsWindow" ... > <Window.Resources> <DataTemplate DataType="{x:Type loc:Person}"> <Grid> <TextBox Text="{Binding PName}" Name="textBox1" ... /> <TextBox Text="{Binding PHeight}" Name="textBox2" ... /> </Grid> </DataTemplate> </Window.Resources> <Grid> <ContentControl Content="{Binding}"/> </Grid> </Window>
Data binding to a collection
C# public partial class PersonsWindow : Window { private ObservableCollection<Person> _dataSource; public PersonsWindow() { _dataSource = new ObservableCollection<Person>(); _dataSource.Add(new Person { PName = "Zbynek", PHeight = 190}); _dataSource.Add(new Person { PName = "Adrian", PHeight = 130 }); DataContext = _dataSource; InitializeComponent(); } }The it is necessary to bind ItemSource property of the ListBox to the data source that is represented as ObservableCollection. View
XAML <Window ... xmlns:loc="clr-namespace:Fundamentals.Binding.DataContext_Collection" > <Window.Resources> <DataTemplate DataType="{x:Type loc:Person}"> <Grid> <TextBox Text="{Binding PName}" ... /> <TextBox Text="{Binding PHeight}" ... /> </Grid> </DataTemplate> </Window.Resources> <Grid> <ListBox ItemsSource="{Binding}" /> </Grid> </Window>
Master-Detail View
Model
C# class Person : INotifyPropertyChanged { public string PName { ... } public double PHeight { ... } public override string ToString() { return PName + " " + Convert.ToString(PHeight); } ... }When user selects an item in ListBox then will be content represented by the return value of Person.ToString() method will be displayed in the TextBox.
View
XAML <Window ... xmlns:loc="clr-namespace:Fundamentals.Binding.DataContext_MasterDetail" > <Grid > <ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" ... > <ListBox.ItemTemplate> <DataTemplate DataType="{x:Type loc:Person}" > <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding PName}"/> <TextBlock Text="{Binding PHeight}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <!-- display selected item: using '/' below ensures that selected item is used {Binding / } => ToString() of selected object (person) is used {Binding / PName} => Name of selected object (person) is used --> <TextBlock Text="{Binding / }" ... /> </Grid> </Window>
Default values
C# <TextBox Text="{Binding Name, FallbackValue='Not found'}" />
Showing and writing null values
XAML <TextBox Text="{Binding MyValue, TargetNullValue=''}" />It can be set a text value as, that will be presented to user and if if user write it down, WPF will write null back to model.
C# <TextBox Text="{Binding Name, TargetNullValue='Null value'}" />
Referencing binding source
- Source
- RelativeSource
- ElementName
Only one of the properties can be set on binding
Source
Use source when you want bind to something else as DataContext
XAML <TextBox Text="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}" />It is possible to avoid using Source by assigning DataContext for the control directly
XAML <TextBox DataContext="{x:Static SystemParameters.WorkArea}" Text="{Binding Width}" />ElementName
XAML <TextBox Name="textBox3" BorderBrush="Red" /> <TextBox BorderBrush="{Binding ElementName=textBox3, Path=BorderBrush}" />
Manipaulate binding in code
textBox1 is type of TextBox
C#
System.Windows.Data.Binding binding = BindingOperations.GetBinding(textBox1, TextBox.TextProperty);
string path = binding.Path.Path;
string elementName = binding.ElementName;
object source = myBinding.Source;
and set
binding as well (without using BindingOperations)
C# System.Windows.Data.Binding myBinding = new System.Windows.Data.Binding(); myBinding.ElementName = "textBox1"; myBinding.Source = label2.Target; myBinding.Path = new PropertyPath("IsEnabled"); label2.SetBinding(TextBox.IsEnabledProperty, myBinding);
Rasing an event with compiler check
C# RaisePropertyChanged(() => this.MyProperty); ... protected void RaisePropertyChanged<TProperty>(Expression<Func<TProperty>> propertyExpression) { var propertyName = ExpressionMiner.ExtractPropertyName(propertyExpression); var handler = this.PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } }
5. Data triggers
Simple data trigger
C# <DataTemplate DataType="{x:Type loc:Person}"> <Grid> <TextBox Text="{Binding PName}" Name="textBox1" ... /> <TextBox Text="{Binding PHeight}" Name="textBox2" ... /> </Grid> <DataTemplate.Triggers> <!-- when the height value is 200 back--> <DataTrigger Binding="{Binding PHeight}" Value="200"> <Setter TargetName="textBox2" Property="Background" Value="Red" /> </DataTrigger> </DataTemplate.Triggers> </DataTemplate>
Animation
C# <DataTemplate DataType="{x:Type loc:Person}"> <Grid> <TextBox Text="{Binding PName}" Name="textBox1" ... /> <TextBox Text="{Binding PHeight}" Name="textBox2" ... /> </Grid> <DataTemplate.Triggers> <!-- when the height value is 200 --> <DataTrigger Binding="{Binding PHeight}" Value="200"> <!-- then textbox turns to Red --> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetName="textBox2" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Red" Duration="0:0:2" /> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> <!-- when changed from 200 to something else then then textbox turns to Green --> <DataTrigger.ExitActions> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetName="textBox2" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="White" Duration="0:0:2" /> </Storyboard> </BeginStoryboard> </DataTrigger.ExitActions> </DataTrigger> </DataTemplate.Triggers> </DataTemplate>
6. Convertors
Standard Convertors
XAML <UserControl.Resources> <BooleanToVisibilityConverter x:Key="BooleanToVisibility" /> </UserControl.Resources>Then is could be used to be bound to PrintInProgress property of bool type.
XAML <Button Content="Cancel" Visibility="{Binding PrintInProgress, Converter={StaticResource BooleanToVisibility}}" Click="..." />
Custom Convertors
C# public class BooleanToVisibilityWithInversionConvertor : IValueConverter { public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture) { if (targetType == typeof(Visibility)) { bool visible = System.Convert.ToBoolean(value, culture); if (parameter.ToString() == "Not") { visible = !visible; } if (InverseVisibility) { visible = !visible; } return visible ? Visibility.Visible : Visibility.Collapsed; } throw new InvalidOperationException("BooleanToVisibility2StatesConvertor can only convert to value of type Visibility."); } public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture) { throw new InvalidOperationException("BooleanToVisibility2StatesConvertor cannot convert back."); } public Boolean InverseVisibility { get; set; } }The convertor can be hardcoded or it can be parametrized.
There are 2 ways. 1 using Property like "InverseVisibility" in this example.
XAML <UserControl.Resources> <myConvertors:BooleanToVisibilityWithInversionConvertor x:Key="BooleanToVisibilityWithInversion" InverseVisibility="True" /> </UserControl.Resources> ... <Grid Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityWithInversion}}" />or using ConvertorParameter like in the example below.
XAML <UserControl.Resources> <myConvertors:BooleanToVisibilityWithInversionConvertor x:Key="BooleanToVisibilityWithInversion" /> </UserControl.Resources> ... <Grid Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityWithInversion}, ConverterParameter='Not'}" />
7. Application start
8. Dependency properties
We can create typical CLR property for our custom controls, e.i. MyStackPanel
C# public class MyStackPanel : StackPanel { private bool _isRed; public bool IsRed { get { return _isRed; } set { _isRed = value; if (_isRed) this.Background = Brushes.Red; else this.Background = Brushes.White; } } }Then we can use it as follow in XAML
XAML <local:MyStackPanel IsRed="True" > <TextBlock>Text 1</TextBlock> </local:MyStackPanel>If we want to create a Dependecy Property ( MSDN ), because we for example need to bound to a value or object that may change, we need to do little more.
DependencyProperty can be implemented only on an object that inhertis from DependencyObject
C# public class MyStackPanel : StackPanel StackPanel inherits from DependencyObject { //register the property - the name must follow the pattern: CLR Property Name + "Property" public static DependencyProperty IsPurpleProperty = DependencyProperty.Register("IsPurple", typeof(bool), typeof(MyStackPanel), // ownerType new FrameworkPropertyMetadata(false, OnIsPurpleChanged)); // create on change handler private static void OnIsPurpleChanged(DependencyObject source, DependencyPropertyChangedEventArgs ev) { bool b = (bool)ev.NewValue; MyStackPanel myStackPanel = source as MyStackPanel; if (b) myStackPanel.Background = Brushes.Purple; else myStackPanel.Background = Brushes.White; } //create CLR property public bool IsPurple { get { return (bool) GetValue(IsPurpleProperty); } set { SetValue(IsPurpleProperty, value); } } }the we can use the CLR property name for binding in XAML
XAML <local:MyStackPanel IsPurple="True" > <TextBlock>Text 1</TextBlock> </local:MyStackPanel>
Dependency properties - example
XAML <Grid> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> <RowDefinition Height="50"/> </Grid.RowDefinitions> <local:MyStackPanel IsRed="False" IsPurple="False" Grid.ColumnSpan="3"> <TextBlock>isRed=false, isPurple=false</TextBlock> </local:MyStackPanel> <local:MyStackPanel Grid.Row="1" IsRed="True" IsPurple="False" Grid.ColumnSpan="3"> <TextBlock>isRed=true, isPurple=false</TextBlock> </local:MyStackPanel> <local:MyStackPanel Grid.Row="2" IsRed="False" IsPurple="True" Grid.ColumnSpan="3"> <TextBlock>isRed=false, isPurple=true</TextBlock> </local:MyStackPanel> <!-- ifyou try to set binding like this: IsRed="{Binding IsRedProp}" you will get runtime error: 'Binding' cannot be set on the 'IsRed' property of type 'MyStackPanel'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. --> <local:MyStackPanel Grid.Row="3" IsPurple="false" Grid.ColumnSpan="3"> <TextBlock>IsRed="{Binding IsRedProp}" <-- is not allowed, isPurple=false</TextBlock> </local:MyStackPanel> <local:MyStackPanel Grid.Row="4" IsRed="False" IsPurple="{Binding IsPurpleProp}" Grid.ColumnSpan="3"> <TextBlock>isRed=false, isPurple="{Binding IsPurpleProp}"</TextBlock> </local:MyStackPanel> </Grid>
C# using System.ComponentModel; namespace Fundamentals.DependencyProperties { public class DPViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged = delegate { }; private bool _isRed; public bool IsRedProp { get { return _isRed; } set { _isRed = value; PropertyChanged(this, new PropertyChangedEventArgs("IsRedProp")); } } private bool _isPurple = true; public bool IsPurpleProp { get { return _isPurple; } set { _isPurple = value; PropertyChanged(this, new PropertyChangedEventArgs("IsPurpleProp")); } } } }
9. Inheritence
C# namespace BaseClasses { public class WindowBase : Window { public WindowBase() {...} public DoSomething() {...} } }2. Create new Window
3. Update NewWindow.xaml
XAML <base:WindowBase .... x:Class="NewWindow" xmlns:base="clr-namespace:BaseClasses"4. Update NewWindow.xaml.cs
Visual Studio create NewWindow as a class inherited from Window
C# public partial class NewWindow : Window { }In order to be able to write
C# BaseWindow newWindow = new NewWindow(); newWindow.DoSomething();it is necessary to remove inheritence from Window and create the class as
C# public partial class NewWindow { }
10. Static and Dynamic resources
11. Commands
WinForms style
XAML <Button Name="btnLikeWinForm" Click="clickCommand_Executed" Content="Click on me" />or in code
C# btnLikeWinForm.Click += clickCommand_Executed;and refer to even handler method
C# void clickCommand_Executed(object sender, EventArgs e) { // do something }When a different event handler is assigned in code and in XAML, the one in code wins. See also DelegateCommand from Telerik below.
Routed commands
XAML <Button Command="ApplicationCommands.Paste" Content="Press Ctrl+V when button is selected"> <Button.CommandBindings> <CommandBinding Command="ApplicationCommands.Paste" Executed="pasteCommand_Executed" /> </Button.CommandBindings> </Button>Event handler in code
XAML void pasteCommand_Executed(object sender, ExecutedRoutedEventArgs e) { // do something }
Custom command
Define the command in your window, user control o isolated view model.
C# public partial class MyControl : UserControl { public static RoutedCommand MyCommand = new RoutedCommand(); private void MyButton_Click(object sender, RoutedEventArgs e) { // execute your operation } private void CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; // implement your logic to decide if the command with associated button are enabled } }In your .xaml file
XAML <Button Content="Click on me" Command="{x:Static local:MyControl.MyCommand}"> <Button.CommandBindings> <CommandBinding Command="{x:Static tabs:MyControl.MyCommand}" Executed="MyButton_Click" CanExecute="CanExecute"/> </Button.CommandBindings> </Button>Based on you decision logic implementation you may need to refresh the UI to reflect changes in model
C# // This may be needed to enable/disable the button associated with the command CommandManager.InvalidateRequerySuggested();
Delegate command - PRISM
It will add references to Prism.dll and Prism.Wpf.dll
C# public partial class MyControl : UserControl { public DelegateCommand MyCommand { get; private set; } internal MyControl() { ... MyCommand = new DelegateCommand(StartExecution, CanExecuteCommand); CanExecute = true; } private bool _canExecute; public bool CanExecute { get { return _canExecute; } set { if (value != _canExecute) { _canExecute = value; PropertyChanged(this, new PropertyChangedEventArgs("CanExecute")); MyCommand.RaiseCanExecuteChanged(); } } } public async void StartExecution() { CanExecute = false; // execute an action CanExecute = true; } private bool CanExecuteCommand() { return _canExecute; } ... }
XAML <Button Content="Click on me" Command="{Binding MyCommand}" />
Telerik DelegateCommand
12. Controls
Grid
Auto - size will be set to accomodate content of the cell
* - will be set as max of remaining space after all Auto rows/columns were calculated
If multiple rows or columns have * specified, their size will be equal. If a row is marked with 2* it means, that its size will twice greater as rows marked with single *
More about Auto vs. *
Sizes can be constrained with Max/Min Height and Width.
XML <Grid> <Grid.RowDefinitions> <RowDefinition Height="150" MinHeight="100"/> <RowDefinition Height="Auto" /> <RowDefinition Height="*" MaxHeight="500"/> </Grid.RowDefinitions> <Button Content="First" /> <Button Content="Second" Grid.Row="1" /> <Button Content="Third" Grid.Row="2" /> </Grid>
GridSplitter
XAML <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" MinWidth="100"/> <ColumnDefinition Width="5" /> <ColumnDefinition Width="Auto" MinWidth="100"/> <ColumnDefinition Width="5"/> <ColumnDefinition Width="*" MinWidth="100"/> </Grid.ColumnDefinitions> <Button Content="Left" Grid.Column="0" HorizontalAlignment="Stretch" /> <GridSplitter Grid.Column="1" Width="5" Background="Yellow" HorizontalAlignment="Center"/> <Button Content="Main" Grid.Column="2" /> <GridSplitter Grid.Column="3" Width="5" Background="Yellow" HorizontalAlignment="Center"/> <Button Content="Right" Grid.Column="4" /> </Grid>When HorizontalAlignment for Splitter is set to "Center" then when the splitter is being moved, the column size, of the column where the splitter resides, will get wider, which means that the column width of the column on the left side from the splitter will remained unchanged.
Label vs. TexBlock
Label can be associated with a TextBox and provides hot Key (_) that works when user presses ALT a causes to set focus on the associated TextBox.
When IsEnabled property for Labal gets set, the Label look will be grayed out, the TextBox look remains.
Label has default Padding that is similar to TextBox.
XAML <Label Content="_My TextBox" Target="{Binding ElementName=textBox1}" IsEnabled="False"/> <TextBox Name="textBox1" Text="Hello"/>As Label can be disabled, it IsEnabled property can be bound to associated TextBox
XAML IsEnabled="{Binding ElementName=textBox1, Path=IsEnabled, Mode=OneWay}
ComboBox
C# public enum Color { Red, Blue, Green }the viewmodel needs to expose the selected value and list of all options
C# private Color _selectedColor; public Color SelectedColor { get { return _selectedColor; } set { if (value != _selectedColor) { _selectedColor = value; this.PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor")); } } } public IEnumerable<Color> AllColors { get { return Enum.GetValues(typeof(Color)).Cast<Color>(); } }XML markup looks like this
XML <ComboBox ItemsSource="{Binding AllColors}" SelectedItem="{Binding SelectedColor}" />
Button - Disable/Enable
C# myButton.IsEnabled = false;it will not cause the button to appear disabled and user still can click the button.
In order the button behaves like a properly disabled buttton, you need to implement a command, bind the command to the button and set CanExecute() on the commnand to false (see commands).
If you set CanExecute to false, it will cause the button to be disabled, but when you set it back to true it will not cause the button to be enabled. The button will get enabled after you change a focus manually (e.g. click Tab). This can be achieved in automated manner by calling
C# CommandManager.InvalidateRequerySuggested();
Scrollable TextBox for a large text
XAML <ScrollViewer MaxHeight="150"> <TextBox Text="Very long text..." /> </ScrollViewer>Without MaxHeight the TextBox, when used in a Grid, will adjust its height to accomodate the text, but the row height in a Grid can make it just partly visible.
User control
Embedding an user control:
XML xmlns:myControlAlias="clr-namespace:myControlNamespace;assembly=myAssemblyNameWithoutDll" ... <Grid> <myControlAlias:MyControl /> </Grid>assembly part is needed only if the user control is located in another assembly
13. Moving from WinForms
Objects names
XAML <Button Content="First" Name="buttonFirst" />Then you can obtain reference to them.
C# Button button1 = this.buttonFirst; object button2 = this.FindName("buttonFirst");
Visibility
Visible: Display the element. Hidden: Do not display the element, but reserve space for the element in layout. Collapsed: Do not display the element, and do not reserve space for it in layout.
Width vs. ActualWidth
Commands
Anchors
XAML Margin="0,40,0,20" Width="auto" Height="auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
DoEvents()
According to MSDN the code below should behave like DoEvents() in WinForms. When I tried it, it did not work in my case.
XAML [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public void DoEvents() { DispatcherFrame frame = new DispatcherFrame(); Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame); Dispatcher.PushFrame(frame); } public object ExitFrame(object f) { ((DispatcherFrame)f).Continue = false; return null; }
Control focus
XAML <Window FocusManager.FocusedElement="{Binding ElementName=MyTextBox}"> <TextBox Name="MyTextBox" Text="{Binding Message}"/> </Window>or in code behind
C# MyTextBox.Focus();
14. Telerik WPF UI
Commands
C# Telerik.Windows.Controls.DelegateCommand : System.Windows.Input.ICommandthe event handler can be assigned directly as delegate
C# public DelegateCommand MyCommand { get; private set; } MyCommand = new DelegateCommand((o1) => {...}, (o2) => { return true; } );it can be assigned directly in code
C# myButton.Command = MyCommand;or in XAML
XAML <telerik:RadButton Name="myButton" Content="Click on me" Command="{Binding MyCommand}">Wenn command validation codition changes, it is necessary to call
C# MyCommand.InvalidateCanExecute();in order to re-evaluate the state. Wenn the command gets executed, CanExecute delegate gets evaluated again.