Declarative vs. procedural design Those who use WinForms know that when a Form gets created, its appearance is defined in CSharp code in
InitializeComponent() method located in *.Designer.cs file. If you examine the method you will see that all controls
are built in sequence. This is true for Java as well
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;
}
<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>
namespace Fundamentals.Binding.DataContext
{
public partial class PersonsWindow : Window
{
public PersonsWindow()
{
InitializeComponent();
}
}
}
More info and samples on: www.devarchweb.net
Layout types/controls As todays devices may have very different screen resolution, from cell phone to smart TV, WPF provides alsoMore info and samples on: www.devarchweb.net
Describe logical tree<Window>
<StackPanel>
<Button Content="Click on me" />
</StackPanel>
</Window>
More info and samples on: www.devarchweb.net
Describe visual tree Button appears visible to user only because a Buttom template was applied to the ButtonMore info and samples on: www.devarchweb.net
How XAML designer loads binaries and how to keep it working XAML designer does not use assemblies from the output folder, but it copies the assembly with the visual class that should present,More info and samples on: www.devarchweb.net
Create one way binding for Person data With one way binding example below the data in the view is set upon creation.class Person
{
public string PName { get; set; }
public string PHeight{ get; set; }
}
<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>
public partial class PersonsWindow : Window
{
private Person _dataSource;
public PersonsWindow()
{
_dataSource = new Person();
_dataSource.PName = "Zbynek";
_dataSource.PHeight = "190";
DataContext = _dataSource;
InitializeComponent();
}
}
More info and samples on: www.devarchweb.net
Create two way binding for Person data With one way binding, when the data in the model got updated, the change was not visible in the view.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 { };
}
public partial class PersonsWindow : Window
{
...
private void btnIncrement_Click(object sender, RoutedEventArgs e)
{
((Person)this.DataContext).PHeight += 1;
}
}
More info and samples on: www.devarchweb.net
Create data template for Person class View<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>
More info and samples on: www.devarchweb.net
Display list of people in ListBox ViewModelpublic 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();
}
}
<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>
More info and samples on: www.devarchweb.net
Master detail For demonstration of Master detail view the Person class (model) class Person : INotifyPropertyChanged
{
public string PName { ... }
public double PHeight { ... }
public override string ToString()
{
return PName + " " + Convert.ToString(PHeight);
}
...
}
<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>
More info and samples on: www.devarchweb.net
Define default value when binding fails<TextBox Text="{Binding Name, FallbackValue='Not found'}" />
More info and samples on: www.devarchweb.net
How to show null value and how to write it back to database<TextBox Text="{Binding MyValue, TargetNullValue=''}" />
<TextBox Text="{Binding Name, TargetNullValue='Null value'}" />
More info and samples on: www.devarchweb.net
How could be source object used for binding referenced Source object for Binding can be specified, if needed, witt he following attributes:<TextBox Text="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}" />
<TextBox DataContext="{x:Static SystemParameters.WorkArea}" Text="{Binding Width}" />
<TextBox Name="textBox3" BorderBrush="Red" />
<TextBox BorderBrush="{Binding ElementName=textBox3, Path=BorderBrush}" />
More info and samples on: www.devarchweb.net
Determine binding in code textBox1 is type of TextBoxSystem.Windows.Data.Binding binding = BindingOperations.GetBinding(textBox1, TextBox.TextProperty);
string path = binding.Path.Path;
string elementName = binding.ElementName;
object source = myBinding.Source;
More info and samples on: www.devarchweb.net
Set binding binding in code (IsEnabled of Label bound to IsEnabled of targeted TextBox)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);
More info and samples on: www.devarchweb.net
How to raise an event that would be checked by compilerRaisePropertyChanged(() => 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));
}
}
More info and samples on: www.devarchweb.net
Create Data trigger to change color of the TextBox when Height value gets set to 200 Model<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>
More info and samples on: www.devarchweb.net
Create Animation with data trigger when value changes Model<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>
More info and samples on: www.devarchweb.net
How to convert boolean to visibility<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibility" />
</UserControl.Resources>
<Button Content="Cancel" Visibility="{Binding PrintInProgress, Converter={StaticResource BooleanToVisibility}}" Click="..." />
More info and samples on: www.devarchweb.net
Implement custom convertor BooleanToVisibilityWithInversionConvertorpublic 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; }
}
More info and samples on: www.devarchweb.net
How to parametrize BooleanToVisibilityWithInversionConvertor (2 ways) There are 2 ways. 1 using Property like "InverseVisibility" in this example.<UserControl.Resources>
<myConvertors:BooleanToVisibilityWithInversionConvertor x:Key="BooleanToVisibilityWithInversion" InverseVisibility="True" />
</UserControl.Resources>
...
<Grid Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityWithInversion}}" />
<UserControl.Resources>
<myConvertors:BooleanToVisibilityWithInversionConvertor x:Key="BooleanToVisibilityWithInversion" />
</UserControl.Resources>
...
<Grid Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityWithInversion}, ConverterParameter='Not'}" />
More info and samples on: www.devarchweb.net
Create IsRed CLR Property for MyStackPanelpublic 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;
}
}
}
<local:MyStackPanel IsRed="True" >
<TextBlock>Text 1</TextBlock>
</local:MyStackPanel>
More info and samples on: www.devarchweb.net
Create IsPurple Dependency Property for MyStackPanelpublic 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); }
}
}
<local:MyStackPanel IsPurple="True" >
<TextBlock>Text 1</TextBlock>
</local:MyStackPanel>
More info and samples on: www.devarchweb.net
What is not allowed in dependency properties <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>
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"));
}
}
}
}
More info and samples on: www.devarchweb.net
How to inherit window from a base class 1. Create base Window classnamespace BaseClasses {
public class WindowBase : Window
{
public WindowBase() {...}
public DoSomething() {...}
}
}
<base:WindowBase
....
x:Class="NewWindow"
xmlns:base="clr-namespace:BaseClasses"
public partial class NewWindow : Window
{
}
BaseWindow newWindow = new NewWindow();
newWindow.DoSomething();
public partial class NewWindow
{
}
More info and samples on: www.devarchweb.net
Difference between static and dynamic resources StaticResourceMore info and samples on: www.devarchweb.net
Command in WinForm like approach Similarly as in WinForm world it possible to assign Click property, either in XAML<Button Name="btnLikeWinForm" Click="clickCommand_Executed" Content="Click on me" />
btnLikeWinForm.Click += clickCommand_Executed;
void clickCommand_Executed(object sender, EventArgs e)
{
// do something
}
More info and samples on: www.devarchweb.net
Routed command with Paste action Routed commands can be associated with any control, not just buttons<Button Command="ApplicationCommands.Paste" Content="Press Ctrl+V when button is selected">
<Button.CommandBindings>
<CommandBinding Command="ApplicationCommands.Paste" Executed="pasteCommand_Executed" />
</Button.CommandBindings>
</Button>
void pasteCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
// do something
}
More info and samples on: www.devarchweb.net
How to create a custom command If you want to create a button that will get disabled after user clicks it and enabled afetr the operation being exeuted has finished,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
}
}
<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>
// This may be needed to enable/disable the button associated with the command
CommandManager.InvalidateRequerySuggested();
More info and samples on: www.devarchweb.net
How to use DelegetaCommand from Prism Install Prism.Wpf Nuget package
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;
}
...
}
<Button Content="Click on me" Command="{Binding MyCommand}" />
More info and samples on: www.devarchweb.net
Grid with height of row definition It is possible to define the height of rows or width of colums either statically with a fixed number<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>
More info and samples on: www.devarchweb.net
Grid with GridSplitters GridSplitter allows changing width of columns or rows in the Grid by mouse.<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>
More info and samples on: www.devarchweb.net
Diffrences between TexBlock and Label Label inherits from ContentControl so it can be represented not only just by text.<Label Content="_My TextBox" Target="{Binding ElementName=textBox1}" IsEnabled="False"/>
<TextBox Name="textBox1" Text="Hello"/>
IsEnabled="{Binding ElementName=textBox1, Path=IsEnabled, Mode=OneWay}
More info and samples on: www.devarchweb.net
Bind ComboBox to enum Having a enum definiton public enum Color { Red, Blue, Green }
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>();
}
}
<ComboBox ItemsSource="{Binding AllColors}" SelectedItem="{Binding SelectedColor}" />
More info and samples on: www.devarchweb.net
How to ensure that a button can get properly disabled/enabled Button control in WPF has property IsEnabled. If you set the property to falsemyButton.IsEnabled = false;
CommandManager.InvalidateRequerySuggested();
More info and samples on: www.devarchweb.net
Scrollable TextBox for large text<ScrollViewer MaxHeight="150">
<TextBox Text="Very long text..." />
</ScrollViewer>
More info and samples on: www.devarchweb.net
How to embed an user controlxmlns:myControlAlias="clr-namespace:myControlNamespace;assembly=myAssemblyNameWithoutDll"
...
<Grid>
<myControlAlias:MyControl />
</Grid>
More info and samples on: www.devarchweb.net
How to name and access objects (e.g.in Window)<Button Content="First" Name="buttonFirst" />
Button button1 = this.buttonFirst;
object button2 = this.FindName("buttonFirst");
More info and samples on: www.devarchweb.net
What are the possible states of Visibility Visible: Display the element.More info and samples on: www.devarchweb.net
What is the differece between Width and ActualWidth Width is the requested width, ActualWidth is actual withd of the control at give moment.More info and samples on: www.devarchweb.net
How to implement like Anchor behavior The same behavior as Anchors in WinForms can be in WPF world achieved by setting Margins.Margin="0,40,0,20"
Width="auto" Height="auto"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
More info and samples on: www.devarchweb.net
How to implement WinForms equivalent of DoEvents()[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;
}
More info and samples on: www.devarchweb.net
How to set focus (2 options) It if is necessary to set only once, it can be done statically either in XAML<Window FocusManager.FocusedElement="{Binding ElementName=MyTextBox}">
<TextBox Name="MyTextBox" Text="{Binding Message}"/>
</Window>
MyTextBox.Focus();
<Window FocusManager.FocusedElement="{Binding ElementName=MyViewModel.FocusedItem}"> < /Window>
More info and samples on: www.devarchweb.net
How to use DelegateCommand Telerik offers own another approch that does not require commandBindingTelerik.Windows.Controls.DelegateCommand : System.Windows.Input.ICommand
public DelegateCommand MyCommand { get; private set; }
MyCommand = new DelegateCommand((o1) => {...}, (o2) => { return true; } );
myButton.Command = MyCommand;
<telerik:RadButton Name="myButton" Content="Click on me" Command="{Binding MyCommand}">
MyCommand.InvalidateCanExecute();