Archive for the ‘WPF’ Category.
Hey all,
I created an MVVM project and then saved it as a template. This way when I create new projects, I can simple choose MVVM Base and save a ton of time.
You can use my template if you want. You can download it here: MVVM Base.zip
If you want this to be available as a new project type in you Visual Studio install, follow these steps.
Hey all,
WPF provides a ProgressBar control. But there isn’t really a manual for it, especially if you want to follow MVVM.
So I am going to make a little application that counts from zero to ten and tracks the progress. You are going to see when it is OK to use the foreground and when it is not OK but better to use BackgroundWorker.
While much of this code may be production ready, you should be aware that this code intentionally implements a foreground process that is an example of what not to do.
There are two basic classes used for MVVM.
These are found on different blogs and different posts all over the internet, so I would say they are public domain, or free and unlicensed.
class ProgressBarViewModel : ViewModelBase
{
}
This will be populated as we create our View.
Ok, so lets create the GUI.
Here is the XAML.
<Window x:Class="WPFProgressBarUsingBackgroundWorker.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFProgressBarUsingBackgroundWorker"
        Title="MainWindow" >
    <Window.Resources>
        <local:ProgressBarViewModel x:Key="PBVM" />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Label Content="{Binding Path=Value}" DataContext="{StaticResource ResourceKey=PBVM}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Name="labelNumberCounter" VerticalAlignment="Center" FontSize="175" />
            <ProgressBar Margin="0,3,0,3" Height="20" Name="progressBar" Value="{Binding Path=Value}" DataContext="{StaticResource ResourceKey=PBVM}" Minimum="{Binding Min}" Maximum="{Binding Max}"/>
            <Button Command="{Binding Path=IncrementBy1}" Content="Manual Count" DataContext="{StaticResource PBVM}" Height="23" IsEnabled="{Binding Path=IsNotInProgress}" Name="button1" Width="Auto" />
            <Button Margin="0,3,0,3" IsEnabled="{Binding Path=IsNotInProgress}" Command="{Binding Path=IncrementAsForegroundProcess}" DataContext="{StaticResource ResourceKey=PBVM}" Content="Count to 10 as a foreground process" HorizontalAlignment="Stretch" Height="23" Name="buttonForeground" VerticalAlignment="Top" Width="Auto" />
            <Button Margin="0,3,0,3" IsEnabled="{Binding Path=IsNotInProgress}" Command="{Binding Path=IncrementAsBackgroundProcess}" DataContext="{StaticResource ResourceKey=PBVM}" Content="Count to 10 as a background process" HorizontalAlignment="Stretch" Height="23" Name="buttonBackground" VerticalAlignment="Top" Width="Auto" />
            <Button Command="{Binding Path=ResetCounter}" Content="Reset" DataContext="{StaticResource PBVM}" Height="23" IsEnabled="{Binding Path=IsNotInProgress}" Name="buttonReset" Width="Auto" />
        </StackPanel>
    </Grid>
</Window>
Here is the code for the ProgressBarViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Text;
using System.Windows.Input;
using MVVM;
namespace WPFProgressBarUsingBackgroundWorker
{
    class ProgressBarViewModel : ViewModelBase
    {
        #region Member Fields
        Double _Value;
        bool _IsInProgress;
        int _Min = 0, _Max = 10;
        #endregion
        #region Member RelayCommands that implement ICommand
        RelayCommand _Increment;
        RelayCommand _IncrementBy1;
        RelayCommand _IncrementAsBackgroundProcess;
        RelayCommand _ResetCounter;
        #endregion
        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public ProgressBarViewModel()
        {
        }
        #endregion
        #region Properties
        /// <summary>
        /// Used to mark if the counter is in progress so the counter can't be started
        /// while it is already running.
        /// </summary>
        public bool IsInProgress
        {
            get { return _IsInProgress; }
            set
            {
                _IsInProgress = value;
                NotifyPropertyChanged("IsInProgress");
                NotifyPropertyChanged("IsNotInProgress");
            }
        }
        public bool IsNotInProgress
        {
            get { return !IsInProgress; }
        }
        public int Max
        {
            get { return _Max; }
            set { _Max = value; NotifyPropertyChanged("Max"); }
        }
        public int Min
        {
            get { return _Min; }
            set { _Min = value; NotifyPropertyChanged("Min"); }
        }
        /// <summary>
        /// This is the Value.  The Counter should display this.
        /// </summary>
        public Double Value
        {
            get { return _Value; }
            set
            {
                if (value <= _Max)
                {
                    if (value >= _Min) { _Value = value; }
                    else { _Value = _Min; }
                }
                else { _Value = _Max; }
                NotifyPropertyChanged("Value");
            }
        }
        #region ICommand Properties
        /// <summary>
        /// An ICommand representation of the Increment() function.
        /// </summary>
        public ICommand IncrementBy1
        {
            get
            {
                if (_IncrementBy1 == null)
                {
                    _IncrementBy1 = new RelayCommand(param => this.Increment());
                }
                return _IncrementBy1;
            }
        }
        /// <summary>
        /// An ICommand representation of the IncrementProgressForegroundWorker() function.
        /// </summary>
        public ICommand IncrementAsForegroundProcess
        {
            get
            {
                if (_Increment == null)
                {
                    _Increment = new RelayCommand(param => this.IncrementProgressForeground());
                }
                return _Increment;
            }
        }
        /// <summary>
        /// An ICommand representation of the IncrementProgressForeground() function.
        /// </summary>
        public ICommand IncrementAsBackgroundProcess
        {
            get
            {
                if (_IncrementAsBackgroundProcess == null)
                {
                    _IncrementAsBackgroundProcess = new RelayCommand(param => this.IncrementProgressBackgroundWorker());
                }
                return _IncrementAsBackgroundProcess;
            }
        }
        /// <summary>
        /// An ICommand representation of the Reset() function.
        /// </summary>
        public ICommand ResetCounter
        {
            get
            {
                if (_ResetCounter == null)
                {
                    _ResetCounter = new RelayCommand(param => this.Reset());
                }
                return _ResetCounter;
            }
        }
        #endregion ICommand Properties
        #endregion
        #region Functions
        /// <summary>
        /// This function manually increments the counter by 1 in the foreground.
        /// Because it only increments by one, the WPF control bound to Value will
        /// display the new value when this function completes.
        /// </summary>
        public void Increment()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;
            // If the value is already at 10, start the counting over.
            if (Value == 10)
                Reset();
            Value++;
        }
        /// <summary>
        /// This function starts the counter as a foreground process.
        /// This doesn't work.  It counts to 10 but the UI is not updated
        /// until the function completes.  This is especially problematic
        /// since the buttons are left enabled.
        /// </summary>
        public void IncrementProgressForeground()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;
            Reset();
            IsInProgress = true;
            Value = 0;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
            IsInProgress = false;
        }
        /// <summary>
        /// This starts the counter as a background process.
        /// </summary>
        public void IncrementProgressBackgroundWorker()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;
            Reset();
            IsInProgress = true;
            BackgroundWorker worker = new BackgroundWorker();
            // Configure the function that will run when started
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            /*The progress reporting is not needed with this implementation and is therefore
            commented out.  However, in your more complex application, you may have a use for
            for this.
            //Enable progress and configure the progress function
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            */
            // Configure the function to run when completed
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            // Launch the worker
            worker.RunWorkerAsync();
        }
        /// <summary>
        /// This is the function that is called when the worker is launched with the RunWorkerAsync() call.
        /// </summary>
        /// <param name="sender">The worker as Object, but it can be cast to a worker.</param>
        /// <param name="e">The DoWorkEventArgs object.</param>
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// This worker_ProgressChanged function is not in use for this project. Thanks to INotifyPropertyChanged, this is
        /// completely unnecessary.
        /// </summary>
        /// <param name="sender">The worker as Object, but it can be cast to a worker.</param>
        /// <param name="e">The ProgressChangedEventArgs object.</param>
        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Does nothing yet
            throw new NotImplementedException();
        }
        /// <summary>
        /// This worker_RunWorkerCompleted is called when the worker is finished.
        /// </summary>
        /// <param name="sender">The worker as Object, but it can be cast to a worker.</param>
        /// <param name="e">The RunWorkerCompletedEventArgs object.</param>
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IsInProgress = false;
        }
        /// <summary>
        /// This function resets the Value of the counter to 0.
        /// </summary>
        private void Reset()
        {
            Value = Min;
        }
        #endregion
    }
}
I’m sorry that this is not the most Newbie proof post. But I tried to comment like crazy the code so you can get through it.
Now if you find a discrepancy in my walk-through, please comment. Also, if it is easier for you to just download the project, here it is:
WPFProgressBarUsingBackgroundWorker.zip
Databinding in WPF allows binding the Command property to methods encapulated in an ICommand. By creating an ICommand object to hold an event function, the Command value can bind to the event function as an ICommand.
The goal of Model-View-ViewModel is to have zero code in the code behind of a WPF Control Instead, everything the WPF Control does happens using databinding.
While this article will show you how to do this, you be left a little fuzzy as to understanding of the implementation. It may take some time and research to fully understand everything this is doing. Understand that methods can be objects, and this is a process to turn a method object into an ICommand so it can be using in WPF for databinding.
You should have Visual Studio 2008/2010.
In Visual Studio, create a new WPF Application project and give it a name.
using System;
using System.Windows.Input;
namespace WpfDataBindingToICommand
{
    public class RelayCommand : ICommand
    {
        #region Constructors
        public RelayCommand()
        {
        }
        #endregion
    }
}
        #region ICommand Members
        public bool CanExecute(object parameter)
        {
            throw new NotImplementedException();
        }
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            throw new NotImplementedException();
        }
        #endregion
        #region Member Variables
        readonly Action<object> _ActionToExecute;
        readonly Predicate<object> __ActionCanExecute;
        #endregion
        public bool CanExecute(object parameter)
        {
            return __ActionCanExecute== null ? true : __ActionCanExecute(parameter);
        }
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        public void Execute(object parameter)
        {
            _ActionToExecute(parameter);
        }
The final class looks as follows:
using System;
using System.Windows.Input;
namespace WpfDataBindingToICommand
{
    /// <summary>
    /// This RelayCommand object is used to encapsulate function logic into an oject that inherits ICommand.
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region Member Variables
        readonly Action<object> _ActionToExecute;
        readonly Predicate<object> _ActionCanExecute;
        #endregion
        #region Constructors
        /// <summary>
        /// This creates a new RelayCommand.
        /// </summary>
        /// <param name="inActionToExecute">This is the logic of the actin to execute. This objects is usually a method that returns void.</param>
        public RelayCommand(Action<object> inActionToExecute)
            : this(inActionToExecute, null)
        {
        }
        /// <summary>
        /// This creates a new RelayCommand.
        /// </summary>
        /// <param name="inActionToExecute">This is the logic of the actin to execute. This objects is usually a method that returns void.</param>
        /// <param name="inActionCanExecute">This is the logic for whether the action can execute.</param>
        public RelayCommand(Action<object> inActionToExecute, Predicate<object> inActionCanExecute)
        {
            if (inActionToExecute == null)
                throw new ArgumentNullException("execute");
            _ActionToExecute = inActionToExecute;
            _ActionCanExecute = inActionCanExecute;
        }
        #endregion
        #region ICommand Members
        public bool CanExecute(object parameter)
        {
            return _ActionCanExecute == null ? true : _ActionCanExecute(parameter);
        }
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        public void Execute(object parameter)
        {
            _ActionToExecute(parameter);
        }
        #endregion
    }
}
Step 2 – Creating a ViewModelBase abstract base class
This object is used to create common logic for all objects that will be using in Binding. This object will implement INotifyPropertyChanged so it only has to be implemented once.
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
        #region Functions
        protected void NotifyPropertyChanged(String inPropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(inPropertyName));
            }
        }
        #endregion
The final object looks as follows:
using System;
using System.ComponentModel;
namespace WpfDataBindingToICommand
{
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        #region Constructors
        public ViewModelBase()
        {
        }
        #endregion
        #region Functions
        protected void NotifyPropertyChanged(String inPropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(inPropertyName));
            }
        }
        #endregion
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}
Note: You may also want to implement IDisposable.
We are going to have the ViewModel and business in the same object for this example, but sometimes you will have a separate ViewModel object that represents your data/business.
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfDataBindingToICommand
{
    public class SampleViewModel : ViewModelBase
    {
        #region Constructors
        public SampleViewModel()
        {
        }
        #endregion
    }
}
    public class SampleViewModel : ViewModelBase
    {
        string _Message = "Hello. This is the default message.";
        public string Message
        {
            get { return _Message; }
            set
            {
                _Message = value;
                NotifyPropertyChanged("Message");
            }
        }
    }
        public void ShowMessage(String inMessage)
        {
            MessageBox.Show(inMessage);
        }
        RelayCommand _ShowMessageCommand;
        public ICommand ShowMessageCommand
        {
            get
            {
                if (_ShowMessageCommand == null)
                {
                    _ShowMessageCommand = new RelayCommand(param => this.ShowMessage(Message));
                }
                return _ShowMessageCommand;
            }
        }
Note: Notice that in order to pass the ShowMessage method, instead of the return value of the function, into the RelayCommand objectwhich is void anyway, the param => syntax is used.
The final SampleViewModel looks as follows.
using System;
using System.Windows;
using System.Windows.Input;
namespace WpfDataBindingToICommand
{
    public class SampleViewModel : ViewModelBase
    {
        #region Member Variables
        string _Message = "Hello. This is the default message.";
        RelayCommand _ShowMessageCommand;
        #endregion
        #region Constructors
        public SampleViewModel()
        {
        }
        #endregion
        #region Properties
        public string Message
        {
            get { return _Message; }
            set
            {
                _Message = value;
                NotifyPropertyChanged("Message");
            }
        }
        public ICommand ShowMessageCommand
        {
            get
            {
                if (_ShowMessageCommand == null)
                {
                    _ShowMessageCommand = new RelayCommand(param => this.ShowMessage(Message));
                }
                return _ShowMessageCommand;
            }
        }
        #endregion
        #region Functions
        public void ShowMessage(String inMessage)
        {
            MessageBox.Show(inMessage);
        }
        #endregion
        #region Enums
        #endregion
    }
}
Ok, so lets modify the XAML of the default MainWindow.xaml code that was auto-created with the project. We will keep it simple and have a text box and a button to pop up the message.
Note: For this simple program all the work we did to implement databinding for binding events to methods seems like an absurd burden. However, for large applications, this design will lead to a better way to manage your code. It will decouple your GUI from your code, making future refactoring of the GUI much easier. This also improves the ability to make minor changes to the GUI. It also makes the code more sustainable and more easily tested. Unit tests are more effective as the GUI layer is not required and most functions are in the business layer.
<window x:Class="WpfDataBindingToICommand.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfDataBindingToICommand"
        Title="MainWindow" Height="350" Width="525">
    <window.Resources>
        <local:SampleViewModel x:Key="Sample" />
    </window.Resources>
        <grid.RowDefinitions>
            <rowDefinition Height="*" />
            <rowDefinition Height="50" />
        </grid.RowDefinitions>
    <grid DataContext="{StaticResource ResourceKey=Sample}">
        <textBox Text="{Binding Message}" Name="textBoxMessage" Margin="5"/>
<button Command="{Binding ShowMessageCommand}" Content="ShowMessage" Grid.Row="1" Height="23" Name="buttonShowMessage" HorizontalAlignment="Right" Width="Auto" Margin="5"/>
You are done. The final XAML is as follows:
<window x:Class="WpfDataBindingToICommand.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfDataBindingToICommand"
        Title="MainWindow" Height="350" Width="525">
    <window.Resources>
        <local:SampleViewModel x:Key="Sample" />
    </window.Resources>
    <grid DataContext="{StaticResource ResourceKey=Sample}">
        <grid.RowDefinitions>
            <rowDefinition Height="*" />
            <rowDefinition Height="50" />
        </grid.RowDefinitions>
        <textBox Text="{Binding Message}" Name="textBoxMessage" Margin="5"/>
        <button Command="{Binding ShowMessageCommand}" Content="ShowMessage" Grid.Row="1" Height="23" Name="buttonShowMessage" HorizontalAlignment="Right" Width="Auto" Margin="5"/>
    </grid>
</window>
Notice that we never touched the code behind of MainWindow. The GUI and the code are as decoupled as possible. Not event the event functions are needed in the code behind. This decoupling or GUI and code is our goal.
WPF Apps With The Model-View-ViewModel Design Pattern
Understanding Routed Events and Commands In WPF
Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.
You have your WPF Window and you have an object that you don’t want to make a static resource. You want to declare it as a member variable in the code.
using System;
using System.ComponentModel;
namespace WPFPerson
{
    public class Person : INotifyPropertyChanged
    {
        #region Member Variables
        String _FirstName;
        String _LastName;
        #endregion
        #region Constructors
        /*
		 * The default constructor
 		 */
        public Person()
        {
        }
        #endregion
        #region Properties
        public String FirstName
        {
            get { return _FirstName; }
            set
            {
                _FirstName = value;
                NotifyPropertyChanged("FirstName");
            }
        }
        public String LastName
        {
            get { return _LastName; }
            set
            {
                _LastName = value;
                NotifyPropertyChanged("LastName");
            }
        }
        #endregion
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }
}
MainWindow.xaml (WPF Window)
<window x:Class="WPFPerson.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 Name="PersonGrid" >
        <textBox Height="23" HorizontalAlignment="Left" Margin="173,87,0,0" Name="textBoxFirstName" VerticalAlignment="Top" Width="234" Text="{Binding FirstName, Mode=TwoWay}" />
        <textBox Height="23" HorizontalAlignment="Left" Margin="173,116,0,0" Name="textBoxLastName" VerticalAlignment="Top" Width="234" Text="{Binding LastName, Mode=TwoWay}"/>
        <label Content="FirstName" Height="28" HorizontalAlignment="Left" Margin="103,85,0,0" Name="labelFirstName" VerticalAlignment="Top" />
        <label Content="LastName" Height="28" HorizontalAlignment="Left" Margin="103,114,0,0" Name="labelLastName" VerticalAlignment="Top" />
        <button Content="Defaults" Height="23" HorizontalAlignment="Left" Margin="337,199,0,0" Name="buttonDefaults" VerticalAlignment="Top" Width="75" Click="buttonDefaults_Click" />
    </grid>
</window>
MainWindow.cs (Code Behind)
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 System.Threading;
namespace WPFPerson
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private readonly Person _Person;
        public MainWindow()
        {
            _Person = new Person();
            InitializeComponent();
            textBoxFirstName.DataContext = _Person;
            textBoxLastName.DataContext = _Person;
        }
        private void buttonDefaults_Click(object sender, RoutedEventArgs e)
        {
            _Person.FirstName = "Jared";
            _Person.LastName = "Barneck";
        }
    }
}
Example 2 – Forthcoming…
Example 3 – Forthcoming…
Sources:
http://www.wrox.com/WileyCDA/Section/Windows-Presentation-Foundation-WPF-Data-Binding-with-C-2005.id-305562.html
Ok, so if you are going to have a string visible in your WPF application and your application can be in multiple languages, you are facing the localization problem.
Usually people as themselves two questions:
The answers are usually not now and I don’t know. So no localization work is done at first. Later, you wish you were more prepared for localization.
Well, I am here to tell you that you can at least prepare to be localized by doing a few simple steps:
If you are going to have a string in your WPF application, it is a good idea to store those strings in a centralized place for localization purposes. Usually in Visual Studio, that is in Resources.resx.
Often a string is entered directly into an the WPF XAML. This is not recommended. Maybe you are thinking that you don’t need to localize your application, so this is not important to you. Ok, really what you are thinking is:
“I don’t know how to do it and if I ever get big enough to need localization, at that point, I will figure it out.”
Well, what if I told you that using Resources.resx is extremely easy?
What if I told you that it hardly takes more time at all?
If it easy and hardly time consuming at all, you would do it, right? I would. Hence this post.
I have a project called LicenseAgreementManager. Right now this only needs to display a license agreement in English, but maybe someday, this will need to display a license agreement in any language.
In Visual Studio, create a new WPF Applcation project.
I named my project LicenseAgreementManager.
Right away, you already have at least one string statically entered into your XAML, the text for the window title.


You now have a publicized Resource.resx file and a few strings inside it.
<window x:Class="LicenseAgreementManager.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>
    </grid>
</window>
<window x:Class="LicenseAgreementManager.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:p="clr-namespace:LicenseAgreementManager.Properties"
        Title="MainWindow" Height="350" Width="525">
<window x:Class="LicenseAgreementManager.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:p="clr-namespace:LicenseAgreementManager.Properties"
        Title="{x:Static p:Resources.EULA_Title}"
        Height="350" Width="525">
That was pretty easy, wasn’t it.
As you add elements that have strings, use the Resources.resx.
I have just added some items and removed the sizing as best as possible. Here is my XAML.
<window x:Class="LicenseAgreementManager.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:p="clr-namespace:LicenseAgreementManager.Properties"
        Title="{x:Static p:Resources.EULA_Title}"
        SizeToContent="WidthAndHeight"
        xml:lang="en-US">
    <grid>
        <grid.RowDefinitions>
            <rowDefinition Height="Auto"/>
            <rowDefinition Height="Auto"/>
        </grid.RowDefinitions>
        <richTextBox Name="_EulaTextBox" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"/>
        <stackPanel Grid.Row="1" Margin="0,10,0,0" Name="stackPanel2" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch">
            <radioButton Content="{x:Static p:Resources.EULA_Accept}" Margin="20,20,20,0" Name="radioButton1" />
            <radioButton Content="{x:Static p:Resources.EULA_NotAccept}" Margin="20,20,20,0" Name="radioButton2" />
            <button Content="{x:Static p:Resources.Next_Button}" Name="button1" Margin="20,20,35,20"  HorizontalAlignment="Right" />
        </stackPanel>
    </grid>
</window>
You don’t have to be localized to be prepared for easy localization. By doing the above simple steps, when it comes time to add localization, you will be ready.
If you want to go on an finish localization. You might want to read some of my sources.
Sources:
http://compositeextensions.codeplex.com/Thread/View.aspx?ThreadId=52910
http://msdn.microsoft.com/en-us/library/ms788718%28v=VS.90%29.aspx
http://msdn.microsoft.com/en-us/library/ms746621.aspx
Copyright ® Rhyous.com – Linking to this article is allowed without permission and as many as ten lines of this article can be used along with this link. Any other use of this article is allowed only by permission of Rhyous.com.
The XAML allows you to provide what are called StaticResources. Such resources can be given to a Window or to certain controls.
For this tutorial, I assume you are in Visual Studio 2008. I assume that you already know how to create a new Project and choose WPF Application. All examples assume you have a new WPF Application.
So lets get started with three examples of binding to StaticResources.
This example will demonstrate instantiating a String as a StaticResource and binding a TextBox to it.
TextBox elements into the default Grid control.
        <listBox Margin="12,12,0,0" Name="listBox1" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" />
        <listBox Margin="138,12,20,0" Name="listBox2" Height="100" VerticalAlignment="Top" />
        <textBox Margin="12,118,0,121" Name="textBox1" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
        <textBox Margin="138,118,20,121" Name="textBox2" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
xmlns reference to the System namespace.  This is done by adding the xmlns:System line to as an attribute to the top Window element as shown:
<window x:Class="StaticResourceBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
Strings to it as StaticResources.
    <window.Resources>
        <system:String x:Key="FirstName">Jared</system:String>
        <system:String x:Key="LastName">Barneck</system:String>
        <system:String x:Key="Alias">Rhyous</system:String>
    </window.Resources>
TextBox elements to bind to each String added as a StaticResource by adding a Text attribute.
        <textBox Text="{StaticResource FirstName}" Height="23" Margin="51,25,107,0" Name="textBox1" VerticalAlignment="Top" />
        <textBox Text="{StaticResource LastName}" Height="23" Margin="51,54,107,0" Name="textBox2" VerticalAlignment="Top" />
        <textBox Text="{StaticResource Alias}" Height="23" Margin="51,83,107,0" Name="textBox3" VerticalAlignment="Top" />
The final XAML looks as follows. No changes were made to the code behind at all.
<window x:Class="StaticResourceBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <window.Resources>
        <system:String x:Key="FirstName">Jared</system:String>
        <system:String x:Key="LastName">Barneck</system:String>
        <system:String x:Key="Alias">Rhyous</system:String>
    </window.Resources>
    <grid>
        <textBox Height="23" Margin="51,25,107,0" Name="textBox1" VerticalAlignment="Top" Text="{StaticResource FirstName}"/>
        <textBox Height="23" Margin="51,54,107,0" Name="textBox2" VerticalAlignment="Top" Text="{StaticResource LastName}"/>
        <textBox Height="23" Margin="51,83,107,0" Name="textBox3" VerticalAlignment="Top" Text="{StaticResource Alias}"/>
    </grid>
</window>
This example will demonstrate instantiating arrays as StaticResources and binding a ListBox to the arrays.
To show an example of building onto existing or previous learned knowledge, we are going to also implement binding each TextBox's Text properties to the ListBox's SelectedItem property.
ListBox and two TextBox elements into the default Grid control.
        <listBox Margin="12,12,0,0" Name="listBox1" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" />
        <listBox Margin="138,12,20,0" Name="listBox2" Height="100" VerticalAlignment="Top" />
        <textBox Margin="12,118,0,121" Name="textBox1" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
        <textBox Margin="138,118,20,121" Name="textBox2" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
xmlns reference to the System namespace.  This is done by adding the xmlns:System line to as an attribute to the top Window element as shown:
<window x:Class="StaticResourceBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <window.Resources>
        <x:Array x:Key="StringList" Type="System:String">
            <system:String>Line 1</system:String>
            <system:String>Line 2</system:String>
            <system:String>Line 3</system:String>
            <system:String>Line 4</system:String>
        </x:Array>
        <x:Array x:Key="IntArray" Type="System:Int32">
            <system:Int32>100</system:Int32>
            <system:Int32>200</system:Int32>
            <system:Int32>300</system:Int32>
            <system:Int32>400</system:Int32>
        </x:Array>
    </window.Resources>
ListBox's Text property to bind to the String array and the other ListBox's Text property to bind to the Int32 array.
        <listBox ItemsSource="{StaticResource StringList}" Margin="12,12,0,0" Name="listBox1" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" />
        <listBox ItemsSource="{StaticResource IntArray}" Margin="138,12,20,0" Name="listBox2" Height="100" VerticalAlignment="Top" />
TextBox to the listBox1.SelectedItem property and bind the other to the listBox2.SelectedItem.
        <textBox Text="{Binding ElementName=listBox1, Path=SelectedItem}" Margin="12,118,0,121" Name="textBox1" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
        <textBox Text="{Binding ElementName=listBox2, Path=SelectedItem}" Margin="138,118,20,121" Name="textBox2" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
The final XAML looks as follows. No changes were made to the code behind at all.
<window x:Class="StaticResourceBinding2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <window.Resources>
        <x:Array x:Key="StringList" Type="System:String">
            <system:String>Line 1</system:String>
            <system:String>Line 2</system:String>
            <system:String>Line 3</system:String>
            <system:String>Line 4</system:String>
        </x:Array>
        <x:Array x:Key="IntArray" Type="System:Int32">
            <system:Int32>100</system:Int32>
            <system:Int32>200</system:Int32>
            <system:Int32>300</system:Int32>
            <system:Int32>400</system:Int32>
        </x:Array>
    </window.Resources>
    <grid>
        <listBox ItemsSource="{StaticResource StringList}" Margin="12,12,0,0" Name="listBox1" Height="100" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" />
        <listBox ItemsSource="{StaticResource IntArray}" Margin="138,12,20,0" Name="listBox2" Height="100" VerticalAlignment="Top" />
        <textBox Text="{Binding ElementName=listBox1, Path=SelectedItem}" Margin="12,118,0,121" Name="textBox1" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
        <textBox Text="{Binding ElementName=listBox2, Path=SelectedItem}" Margin="138,118,20,121" Name="textBox2" Width="120" IsReadOnly="True" HorizontalAlignment="Left" />
    </grid>
</window>
In the previous two examples, we added the resources to the main Window object. However, a resource can be added to a control.
This example will demonstrate instantiating an array as a StaticResources for a control. We will then bind a TabControl’s ItemSource property to this array.  This will cause a Tab to be created for each item in the array.
TabControl into the default Grid control.
        <tabControl Name="tabControl1">
xmlns reference to the System namespace.  This is done by adding the xmlns:System line to as an attribute to the top Window element as shown:
<window x:Class="StaticResourceBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
Grid.Resources section in the XAML and add an array as a StaticResource under the Grid control.
        <grid.Resources>
            <x:Array x:Key="TabList" Type="System:String">
                <system:String>Tab 1</system:String>
                <system:String>Tab 2</system:String>
                <system:String>Tab 3</system:String>
            </x:Array>
        </grid.Resources>
TabControl's ItemSource property to bind to the String array.
        <tabControl Name="tabControl1" ItemsSource="{StaticResource TabList}">
The final XAML looks as follows. No changes were made to the code behind at all.
<window x:Class="StaticResourceBinding3.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib"
    Title="Window1" Height="300" Width="300">
    <grid>
        <grid.Resources>
            <x:Array x:Key="TabList" Type="System:String">
                <system:String>Tab 1</system:String>
                <system:String>Tab 2</system:String>
                <system:String>Tab 3</system:String>
            </x:Array>
        </grid.Resources>
        <tabControl Name="tabControl1" ItemsSource="{StaticResource TabList}">
        </tabControl>
    </grid>
</window>
Hey, there is nothing wrong with more examples, so if you have an example of your own feel free to add it as a comment.
Copyright ® Rhyous.com – Linking to this post is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.
Today I needed a progress bar for as I was creating a c# tool that FTPs a file. I wanted to show progress as the FTP file was uploaded.
I found a good solution at Mikes Code Blog. He has a post and a follow-up post.
I created the progress bar as described and it worked really well. Here is a screen shot:
Thanks Mike!
The properties of WPF elements can be bound to properties of other WPF Elements. Lets do some simple examples of binding one element to another.
For this tutorial, I assume you are in Visual Studio 2008. I assume that you already know how to create a new Project and choose WPF Application. All examples assume you have a new WPF Application.
I am the believer that one example isn’t enough, so I am going to give you three examples:
This example will demonstrate binding a Button‘s IsEnabled property to a CheckBox‘s IsChecked property.
CheckBoxButtonThe Button is named button1 and the CheckBox is named checkBox1.
checkBox1 to “Enable button”.  This can be done either in the Properties or in the XAML.button1 element.button1 element:IsEnabled="{Binding ElementName=checkBox1, Path=IsChecked}"In your project, ElementName could be any item. In this example, we only have two elements so far: button1, and checkBox1.The XAML now looks like this (only two new lines exist):
<Window x:Class="BindingATextBoxToASlider.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Button Content="Button" Height="23" Margin="12,34,416,0" Name="button1" VerticalAlignment="Top" Width="75" IsEnabled="{Binding ElementName=checkBox1, Path=IsChecked}"/>
        <CheckBox Content="CheckBox" Height="16" Margin="12,12,408,0" Name="checkBox1" VerticalAlignment="Top" />
    </Grid>
</Window>
Ok, so that was pretty cool. We have a simple example of binding one Element to another.
Yes, you can shoot yourself in the foot by doing something stupid.
You could bind an element to itself. Let’s try it just so you can see it happen.
Add the same binding you added to button1 to checkBox1.
Compile and see what happens.
This example uses a Slider and a TextBox.
TextBoxSliderThe Slider is named slider1 and the TextBox is named textBox1.
textBox1 element.textBox1 element:Text="{Binding ElementName=slider1, Path=Value}"ElementName can be any item. In this example, we only have two elements so far: slider1, and textBox1.The XAML now looks like this (only two new lines exist):
<Window x:Class="BindingATextBoxToASlider.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
       <TextBox Height="23" Margin="79,62,99,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding ElementName=slider1, Path=Value}"/>
        <Slider Height="22" Margin="79,34,99,0" Name="slider1" VerticalAlignment="Top" />
    </Grid>
</Window>
Ok, so maybe you want to try to do calculations in the XAML Binding. It doesn’t work.
You can enter this and while it will compile, the Binding won’t work:
Text="{Binding ElementName=slider1, Path=(int)Value}"
You can enter this and while it will compile, the Binding won’t work:
Text="{Binding ElementName=slider1, Path=Value + 1}"
Ok, lets do a slight more complex example.  We are going to have more than two elements.  We are going to have a ListBox that contains a list of items (ListBoxItems).  We are going to have a TextBox that displays the content of the selected item.
TextBoxListBoxlistBox1. This can be done either in the XAML or by clicking on the button for Items in the Properties of the listBox1.textBox1 element.textBox1 element:Text="{Binding ElementName=listBox1, Path=SelectedItem.Content}"Notice that we are using a property of a property for the Path.  This is allowed.  SelectedItem is a property of listBox1, and Content is a property of SelectedItem.The XAML now looks like this (only two new lines exist):
<Window x:Class="BindingATextBoxToAListBoxSelectedItem.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <TextBox Height="23" Margin="12,23,12,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding ElementName=listBox1, Path=SelectedItem.Content}"/>
        <ListBox Margin="12,52,12,110" Name="listBox1">
            <ListBoxItem>c:</ListBoxItem>
            <ListBoxItem>d:</ListBoxItem>
            <ListBoxItem>e:</ListBoxItem>
            <ListBoxItem>f:</ListBoxItem>
            <ListBoxItem>g:</ListBoxItem>
            <ListBoxItem>h:</ListBoxItem>
        </ListBox>
    </Grid>
</Window>
Copyright ® Rhyous.com – Linking to this post is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.
This document assumes that you understand the concepts of object oriented programming and more specifically with C# programming, such as Classes or Objects, Methods, Properties, Events, etc.  If not, it will be much harder to follow along.
This tutorial will cover the basics of data Binding in a WPF application.  When you are done with this tutorial, you should be able to create a basic WPF-based graphical program that uses Binding.  We will cover the different types of data Binding as well as what works and sometimes what doesn’t.
The idea of data Binding is to link a variable of any Type (int, string, object, etc…) to a graphical object’s Property that has the same type.
For example, lets say you have a Button object called myButton in your GUI like this: .  The words “Click Me!” is a string property in the Button object: myButton.Text.
Imagine you have a string variable called strProperty in some part of your code that on its own has no way to interact with your GUI code. Lets say you want to change the myButton.Text property to match that string variable.  Binding allows the button’s text string to always match a string property  in some other object not really related to your GUI so if you change strProperty to equal “Enable” your button text will look like . If you then change the strProperty to “Disable” the button text will automatically change to be  without out your back end code having to make any interaction with the GUI on its own.
Without Binding, you would have to write code yourself that would interact with the GUI and update the myButton.Text property when ever you update the string in code.  In order to do this without Binding, you would also have to intermingle your background code with your GUI code.  This can make it difficult to update or modify your GUI because GUI code is strung throughout all parts of your application. You don’t just have to update your GUI, you have to update all your code that interacts with the GUI.
So Binding allows you to have a back end code that is independent of the GUI.  This is especially useful when the GUI needs to be updated or improved or when multiple GUIs exists (skins) and you can switch between them.
There are programming styles associated with developing a GUI separate from the back-end. Two of which are Model-View-Control (MVC) or Model-View-ViewModel (MVVM). This tutorial is not going to cover these, however, it is probably wise for you become familiar with these.
However, there is no reason you are limited to Binding to back end code.  You can bind to code that is in the WPF GUI and very powerful applications can be written with little to no back end code.
In order to using data Binding, you should have the following requirements:
System.ComponentModel.INotifyPropertyChanged.There is are multiple types of Binding.  Elements bind to some type of resource and there are multiple types of resources.  Static and Dynamic resource binding which uses the StaticResource  Markup Extension or the DynamicResource  Markup Extension.
The Binding source can also be “any public property, including properties of other controls, common  language runtime (CLR) objects, XAML elements, ADO.NET DataSets, XML  Fragments, and so forth.” (Reference: http://msdn.microsoft.com/en-us/magazine/cc163299.aspx).
Go to next: 1.1 Binding one element property to another
Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.