Use Data Triggers to Change the Appearance of Bound Data

image_pdfimage_print


   
  
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WpfApplication1="clr-namespace:WpfApplication1"
    x:Name="thisWindow" Title="WPF" Height="240" Width="280">

    <Window.Resources>
        <WpfApplication1:DataItems x:Key="dataItems"/>
        <WpfApplication1:AmountToHeightConverter x:Key="amountToHeightConverter" />
        <DataTemplate x:Key="dataItemtemplate">
            <Rectangle x:Name="rectangle" Width="30"
                VerticalAlignment="Bottom"
                Fill="Green"
                Height="{Binding Path=Amount,Converter={StaticResource amountToHeightConverter}}"/>
            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding Path=IsPositive}" Value="False">
                    <Setter TargetName="rectangle" Property="Fill" Value="Red"/>
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </Window.Resources>
    <StackPanel>
        <ItemsControl ItemsSource="{Binding Source={StaticResource dataItems}}"
            ItemTemplate="{StaticResource dataItemtemplate}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>

        <Line Stroke="Black" StrokeThickness="2" X1="0" Y1="0" X2="0" Y2="{Binding ElementName=thisWindow, Path=ActualHeight}"/>
        <Line Stroke="Black" StrokeThickness="2" X1="0" Y1="0" X2="{Binding ElementName=thisWindow, Path=ActualWidth}" Y2="0"/>
    </StackPanel>
</Window>
//File:Window.xaml.cs
using System;
using System.Windows.Data;
using System.Globalization;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
    [ValueConversion(typeof (double), typeof (double))]
    public class AmountToHeightConverter : IValueConverter
    {
        public Object Convert(Object value,Type targetType,Object parameter,CultureInfo culture)
        {
            double amount = System.Convert.ToDouble(value);
            if(amount < 0)
                amount = 0;

            return amount;
        }
        public object ConvertBack(object value,Type targetType,object parameter,CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    public class DataItem
    {
        public double Amount
        {
            get;
            set;
        }

        public bool IsPositive
        {
            get
            {
                return Amount >= 0;
            }
        }
    }

    public class DataItems : Collection<DataItem>
    {
        public DataItems()
        {
            this.Add(new DataItem(){Amount=5});
            this.Add(new DataItem(){Amount=8});
            this.Add(new DataItem(){Amount=-5});
            this.Add(new DataItem(){Amount=2});
            this.Add(new DataItem(){Amount=-5});
            this.Add(new DataItem(){Amount=-5});
        }
    }
}

   
    
     


DependencyProperty.RegisterReadOnly to create read only Dependency Property

image_pdfimage_print


   
  

<Window x:Name="winThis" x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="Create a Read-Only Dependency Property" Height="300" Width="300">
    <Grid>
      <Viewbox>
        <TextBlock Text="{Binding ElementName=winThis, Path=Counter}" />
      </Viewbox>
    </Grid>
</Window>

//File:Window.xaml.cs
using System;
using System.Windows;
using System.Windows.Threading;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DispatcherTimer timer = 
                new DispatcherTimer(TimeSpan.FromSeconds(1), 
                                    DispatcherPriority.Normal, 
                                    delegate 
                                    {
                                        int newValue = Counter == int.MaxValue ? 0 : Counter + 1;
                                        SetValue(counterKey, newValue); 
                                    }, 
                                    Dispatcher);
        }

        public int Counter
        {
            get { return (int)GetValue(counterKey.DependencyProperty); }
        }

        private static readonly DependencyPropertyKey counterKey = 
            DependencyProperty.RegisterReadOnly("Counter", 
                                                typeof(int), 
                                                typeof(Window1), 
                                                new PropertyMetadata(0));
    }
}

   
    
     


Clear locally set values and restore the default values of dependency properties

image_pdfimage_print


   
  
<StackPanel Name="root"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="WpfApplication1.DPClearValue">
    <StackPanel.Resources>
      <Style TargetType="Button">
        <Setter Property="Height" Value="20"/>
        <Setter Property="Width" Value="250"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
      </Style>
      <Style TargetType="Ellipse">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Width" Value="50"/>
        <Setter Property="Fill" Value="Black"/>
      </Style>
      <Style TargetType="Rectangle">
        <Setter Property="Height" Value="50"/>
        <Setter Property="Width" Value="50"/>
        <Setter Property="Fill" Value="Blue"/>
      </Style>
      <Style TargetType="Polygon">
        <Setter Property="Points" Value="10,60 60,60 60,10"/>
        <Setter Property="Fill" Value="Blue"/>
      </Style>
      <Style x:Key="ShapeStyle" TargetType="Shape">
        <Setter Property="Fill" Value="Red"/>
      </Style>
    </StackPanel.Resources>
  <DockPanel Name="myDockPanel">
    <Ellipse Height="100"  Width="100" Style="{StaticResource ShapeStyle}"/>
    <Rectangle Height="100" Width="100"  Style="{StaticResource ShapeStyle}" />
    <Polygon Points="10,110 110,110 110,10" Style="{StaticResource ShapeStyle}"/>
  </DockPanel>
    <Button Name="RedButton" Click="MakeEverythingRed">Make everything red</Button>
    <Button Name="ClearButton" Click="RestoreDefaultProperties">
  Clear local values
  </Button>

</StackPanel>

//File:Window.xaml.cs


using System.Windows;
using System.Collections;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Shapes;

namespace WpfApplication1 {
    public partial class DPClearValue {
        void RestoreDefaultProperties(object sender, RoutedEventArgs e)
        {
            UIElementCollection uic = myDockPanel.Children;
            foreach (Shape uie in uic)
            {
                LocalValueEnumerator locallySetProperties = uie.GetLocalValueEnumerator();
                while (locallySetProperties.MoveNext())
                {
                    DependencyProperty propertyToClear = (DependencyProperty)locallySetProperties.Current.Property;
                    if (!propertyToClear.ReadOnly) { uie.ClearValue(propertyToClear); }
                }
            }
        }
        void MakeEverythingRed(object sender, RoutedEventArgs e)
        {
            UIElementCollection uic = myDockPanel.Children;
            foreach (Shape uie in uic) {uie.Fill = new SolidColorBrush(Colors.Red);}
        }
    }
}

   
    
     


Add a PropertyChangedValueCallback to Any Dependency Property

image_pdfimage_print


   
  
<Window x:Class="WpfApplication1.Window1"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title=" " Height="300" Width="300" Loaded="Window1_Loaded">
  <Grid>
    <Viewbox>
      <TextBox x:Name="tbxEditMe" Text="Edit Me..." />
    </Viewbox>      
  </Grid>
</Window>


//File:Window.xaml.cs
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window1_Loaded(object sender, RoutedEventArgs e)
        {
            DependencyPropertyDescriptor descriptor = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
            descriptor.AddValueChanged(tbxEditMe, tbxEditMe_TextChanged);
            
        }

        private void tbxEditMe_TextChanged(object sender, EventArgs e)
        {
            MessageBox.Show("", "changed");
        }
    }
}

   
    
     


Unblock Thread with Dispatcher.BeginInvoke

image_pdfimage_print


   
  
<Window x:Class="WPFThreading.UnblockThread"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="UI Thread Blocker" Height="275" Width="225">
    <StackPanel>
      <Button Name="button1" Click="button1_click">Go to sleep</Button>
      <Button Name="button2" Click="button2_click">Try Me</Button>
      <TextBox Name="textbox1"/>
      <Label Name="UIThreadLabel"></Label>
      <Label Name="BackgroundThreadLabel"></Label>
    </StackPanel>
</Window>
//File:Window.xaml.cs

using System.Windows;
using System.Windows.Threading;
using System.Threading;

namespace WPFThreading
{
  public partial class UnblockThread : System.Windows.Window
  {
    private delegate void SimpleDelegate();
    public UnblockThread()
    {
      InitializeComponent();

      this.UIThreadLabel.Content = this.Dispatcher.Thread.ManagedThreadId;
      this.BackgroundThreadLabel.Content = "N/A";
    }

    private void LongRunningProcess() 
    {
      SimpleDelegate del1 = delegate(){ this.BackgroundThreadLabel.Content = Thread.CurrentThread.ManagedThreadId; };
      this.Dispatcher.BeginInvoke(DispatcherPriority.Send, del1);

      Thread.Sleep(5000);

      SimpleDelegate del2 = delegate() {this.textbox1.Text = "Done Sleeping...";};
      this.Dispatcher.BeginInvoke(DispatcherPriority.Send, del2);
    }

    private void button1_click(object sender, RoutedEventArgs e)
    {
      SimpleDelegate del = new SimpleDelegate(LongRunningProcess);
      del.BeginInvoke(null, null);
    }

    private void button2_click(object sender, RoutedEventArgs e)
    {
      this.textbox1.Text = "Hello WPF";
    }

  }
}

   
    
     


DispatcherTimer and EventHandler

image_pdfimage_print


   
  


<Window x:Class="Holding.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="FillingExample" Height="300" Width="300">
  <Canvas>
    <Ellipse Name="myEllipse" Height="100" Fill="Red">
      <Ellipse.Triggers>
        <EventTrigger RoutedEvent="Ellipse.Loaded">
          <BeginStoryboard>
            <Storyboard>
              <DoubleAnimation BeginTime="0:0:2" Duration="0:0:5"
                  Storyboard.TargetProperty="(Ellipse.Width)"
                  From="10" To="300" FillBehavior="Stop" />

            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Ellipse.Triggers>
    </Ellipse>
  </Canvas>
</Window>
//File:Window.xaml.cs

using System;
using System.Windows;
using System.Windows.Threading;
using System.Diagnostics;

namespace Holding
{
    public partial class Window2 : Window
    {
        DispatcherTimer t = new DispatcherTimer();
        DateTime start;
        public Window2()
        {
            InitializeComponent();
            t.Tick += new EventHandler(OnTimerTick);
            t.Interval = TimeSpan.FromSeconds(0.5);
            t.Start();
            start = DateTime.Now;
        }
        void OnTimerTick(object sender, EventArgs e)
        {
            TimeSpan elapsedTime = DateTime.Now - start;
            Debug.WriteLine(elapsedTime.ToString() + ": " + myEllipse.Width);
        }
    }
}

   
    
     


Dispatcher.BeginInvoke with DispatcherPriority.Normal

image_pdfimage_print


   
  

<Window x:Class="DispatcherExamples.UseVerifyAccess"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="DispatcherExamples" Height="300" Width="300"
    >
    <Grid>
        <StackPanel>
            <Button Content="Call from UI Thread" x:Name="fromUiButton" />
            <TextBlock x:Name="result" TextWrapping="Wrap" />
        </StackPanel>
    </Grid>
</Window>
//File:Window.xaml.cs
using System;
using System.Collections.Generic;
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.Shapes;
using System.Threading;
using System.Windows.Threading;

namespace DispatcherExamples
{
    public partial class UseVerifyAccess : System.Windows.Window
    {

        public UseVerifyAccess()
        {
            InitializeComponent();

            fromUiButton.Click += new RoutedEventHandler(fromUiButton_Click);
        }

        void fromUiButton_Click(object sender, RoutedEventArgs e)
        {
            string resultText;
            try
            {
                resultText = "Success";
            }
            catch (Exception x)
            {
                resultText = x.ToString();
            }
            Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate
            {
                result.Text = resultText;
            });
        }
    }
}