Blog Home  Home Feed your aggregator (RSS 2.0)  
kevin Mocha - DotNet | WPF
Bookmarks collected from web.
 
 Monday, May 03, 2010

http://stackoverflow.com/questions/58739/interview-questions-wpf-developer

What should every WPF developer know?

Entry Level

  • Strong .NET 2.0 Background & willing to learn!
  • Explain dependency properties?
  • What's a style?
  • What's a template?
  • Binding
  • Differences between base classes: Visual, UIElement, FrameworkElement, Control
  • Visual vs Logical tree?
  • Property Change Notification (INotifyPropertyChange and ObservableCollection)
  • ResourceDictionary - Added by a7an
  • UserControls - Added by a7an
  • difference between bubble and tunnel routing strategies - added by Carlo

Mid-level

  • Routed Events & Commands
  • Converters - Added by Artur Carvalho
  • Explain WPF's 2-pass layout engine?
  • How to implement a panel?
  • Interoperability (WPF/WinForms)
  • Blend/Cider - Added by a7an
  • animations and storyboarding
  • ClickOnce Deployment
  • Skinning/Themeing
  • Custom Controls
  • How can worker threads update the UI?

Senior

  • Example of attached behavior?
  • What is PRISM,CAL & CAG?
  • How can worker threads update the UI?
  • WPF 3D - Added by a7an
  • Differences between Silverlight 2 and WPF
  • MVVM/MVP - Added by a7an
  • WPF Performance tuning
  • Pixel Shaders
  • Purpose of Freezables
Monday, May 03, 2010 3:49:48 AM UTC  #    Comments [0]    |  Trackback
 Saturday, March 20, 2010
 Friday, March 19, 2010

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

M-V-VM pattern

The PM pattern is similar to MVP in that it separates a view from its behavior and state. The interesting part of the PM pattern is that an abstraction of a view is created, called the Presentation Model. A view, then, becomes merely a rendering of a Presentation Model. In Fowler's explanation, he shows that the Presentation Model frequently updates its View, so that the two stay in sync with each other. That synchronization logic exists as code in the Presentation Model classes.

Unlike the Presenter in MVP, a ViewModel does not need a reference to a view. The view binds to properties on a ViewModel, which, in turn, exposes data contained in model objects and other state specific to the view. The bindings between view and ViewModel are simple to construct because a ViewModel object is set as the DataContext of a view. If property values in the ViewModel change, those new values automatically propagate to the view via data binding. When the user clicks a button in the View, a command on the ViewModel executes to perform the requested action. The ViewModel, never the View, performs all modifications made to the model data.

The single most important aspect of WPF that makes MVVM a great pattern to use is the data binding infrastructure. By binding properties of a view to a ViewModel, you get loose coupling between the two and entirely remove the need for writing code in a ViewModel that directly updates a view. The data binding system also supports input validation, which provides a standardized way of transmitting validation errors to a view.

 

Two other features of WPF that make this pattern so usable are data templates and the resource system. Data templates apply Views to ViewModel objects shown in the user interface. You can declare templates in XAML and let the resource system automatically locate and apply those templates for you at run time. You can learn more about binding and data templates in my July 2008 article, "Data and WPF: Customize Data Display with Data Binding and WPF."

 

If it were not for the support for commands in WPF, the MVVM pattern would be much less powerful. In this article, I will show you how a ViewModel can expose commands to a View, thus allowing the view to consume its functionality. If you aren't familiar with commanding, I recommend that you read Brian Noyes's comprehensive article, "Advanced WPF: Understanding Routed Events and Commands in WPF," from the September 2008 issue.

 

In addition to the WPF (and Silverlight 2) features that make MVVM a natural way to structure an application, the pattern is also popular because ViewModel classes are easy to unit test. When an application's interaction logic lives in a set of ViewModel classes, you can easily write code that tests it. In a sense, Views and unit tests are just two different types of ViewModel consumers. Having a suite of tests for an application's ViewModels provides free and fast regression testing, which helps reduce the cost of maintaining an application over time.

 

In addition to promoting the creation of automated regression tests, the testability of ViewModel classes can assist in properly designing user interfaces that are easy to skin. When you are designing an application, you can often decide whether something should be in the view or the ViewModel by imagining that you want to write a unit test to consume the ViewModel. If you can write unit tests for the ViewModel without creating any UI objects, you can also completely skin the ViewModel because it has no dependencies on specific visual elements.

 

Lastly, for developers who work with visual designers, using MVVM makes it much easier to create a smooth designer/developer workflow. Since a view is just an arbitrary consumer of a ViewModel, it is easy to just rip one view out and drop in a new view to render a ViewModel. This simple step allows for rapid prototyping and evaluation of user interfaces made by the designers.

The development team can focus on creating robust ViewModel classes, and the design team can focus on making user-friendly Views. Connecting the output of both teams can involve little more than ensuring that the correct bindings exist in a view's XAML file.

 

Relaying Command Logic

Every view in the app has an empty codebehind file, except for the standard boilerplate code that calls InitializeComponent in the class's constructor. In fact, you could remove the views' codebehind files from the project and the application would still compile and run correctly. Despite the lack of event handling methods in the views, when the user clicks on buttons, the application reacts and satisfies the user's requests. This works because of bindings that were established on the Command property of Hyperlink, Button, and MenuItem controls displayed in the UI. Those bindings ensure that when the user clicks on the controls, ICommand objects exposed by the ViewModel execute. You can think of the command object as an adapter that makes it easy to consume a ViewModel's functionality from a view declared in XAML.

When a ViewModel exposes an instance property of type I­Command, the command object typically uses that ViewModel object to get its job done. One possible implementation pattern is to create a private nested class within the ViewModel class, so that the command has access to private members of its containing ViewModel and does not pollute the namespace. That nested class implements the ICommand interface, and a reference to the containing ViewModel object is injected into its constructor. However, creating a nested class that implements ICommand for each command exposed by a ViewModel can bloat the size of the ViewModel class. More code means a greater potential for bugs.

In the demo application, the RelayCommand class solves this problem. RelayCommand allows you to inject the command's logic via delegates passed into its constructor. This approach allows for terse, concise command implementation in ViewModel classes. RelayCommand is a simplified variation of the DelegateCommand found in the Microsoft Composite Application Library.

 

 

Data-binding in WPF

 

 

http://www.nbdtech.com/Free/WpfBinding.pdf

 

image

 

image

image

image

image

image

image

Friday, March 19, 2010 8:12:42 PM UTC  #    Comments [0]    |   |  Trackback
 Friday, September 04, 2009
 Monday, August 31, 2009

http://geekswithblogs.net/claraoscura/archive/2008/10/17/125901.aspx

“The solution I have found is to put each radio button in a different group and link their checked/unchecked values via the converter. Like this:”

       <RadioButton 
                Grid.Row="1"
                Grid.Column="0"
                GroupName="rbGroupSuccess"
                Margin="8,0,0,0"
                VerticalAlignment="Center"                
                Content="Success"
                x:Name="rbSuccess" 
                IsChecked="{Binding Path=IsSuccess, Mode=TwoWay, Converter={StaticResource nullableBooleanConverter}, ConverterParameter=true}" />
        
        <RadioButton 
                Grid.Row="1"
                Grid.Column="1"
                GroupName="rbGroupFailure"
                Margin="8,0,0,0"
                VerticalAlignment="Center"
                Content="Failure"               
                x:Name="rbFailure"    
                IsChecked="{Binding Path=IsSuccess, Mode=TwoWay, Converter={StaticResource nullableBooleanConverter}, ConverterParameter=false}" />

 

 

    [ValueConversion(typeof(bool?), typeof(bool))]
    public class SuccessConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool param = bool.Parse(parameter.ToString());
            if (value == null)
            {
                return false;
            }
            else
            {
                return !((bool)value ^ param);
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool param = bool.Parse(parameter.ToString());
            return !((bool)value ^ param);
        }
    }
Monday, August 31, 2009 12:54:45 PM UTC  #    Comments [0]    |  Trackback
 Wednesday, August 19, 2009
 Friday, August 14, 2009
 Tuesday, June 16, 2009
 Wednesday, June 10, 2009

 

Sachabarber’s extension method http://sachabarber.net/?p=411 (Five start solution)

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/82c6451d-d37b-4380-aa11-d75c2f759ba7/

XAML:
<Window x:Class="WindowsApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Testing BackgroundWorker" Height="300" Width="300" 
    > 
    <Grid> 
        <Button HorizontalAlignment="Left" Margin="8,25,0,0" x:Name="_btnStart" VerticalAlignment="Top" Width="87" Height="27" Content="Start" Click="StartWorker"/> 
        <Button IsEnabled="False" Margin="99,25,102,0" x:Name="_btnCancel" VerticalAlignment="Top" Height="27" Content="Cancel" Click="CancelWorker"/> 
        <ProgressBar Margin="8,0,8,107" x:Name="_progressBar" VerticalAlignment="Bottom" Height="23" Maximum="10"/> 
    </Grid> 
</Window> 
C#:
using System.ComponentModel; 
using System.Threading; 
using System.Windows; 
namespace WindowsApplication1 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : System.Windows.Window 
    { 
        private BackgroundWorker _worker; 
        public Window1() 
        { 
            InitializeComponent(); 
        } 
        private void StartWorker(object sender, RoutedEventArgs e) 
        { 
            int N = 10; 
            _worker = new BackgroundWorker(); 
            _worker.WorkerReportsProgress = true; 
            _worker.WorkerSupportsCancellation = true; 
            _worker.DoWork += delegate(object s, DoWorkEventArgs args) 
                { 
                    BackgroundWorker worker = s as BackgroundWorker; 
                    for (int i = 0; i < N; i++) 
                    { 
                        if (worker.CancellationPending) 
                        { 
                            args.Cancel = true; 
                            return; 
                        } 
                        Thread.Sleep(1000); 
                        worker.ReportProgress(i + 1); 
                    } 
                }; 
            _worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args) 
                { 
                    _progressBar.Value = args.ProgressPercentage; 
                }; 
            _worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) 
                { 
                    _btnStart.IsEnabled = true; 
                    _btnCancel.IsEnabled = false; 
                    _progressBar.Value = 0; 
                }; 
            _worker.RunWorkerAsync(); 
            _btnStart.IsEnabled = false; 
            _btnCancel.IsEnabled = true; 
        } 
        private void CancelWorker(object sender, RoutedEventArgs e) 
        { 
            _worker.CancelAsync(); 
        } 
    } 
} 
Wednesday, June 10, 2009 6:00:32 PM UTC  #    Comments [0]    |   |  Trackback
 Tuesday, June 09, 2009

Coroutines with IEnumnberable and yield return http://incrediblejourneysintotheknown.blogspot.com/2008/04/coroutines-with-ienumerable-and-yield.html

Forcing Update of UI before my function exists http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6fce9b7b-4a13-4c8d-8c3e-562667851baa/

An even easier method has just occurred to me: just call this method after setting UI properties:

void AllowUIToUpdate() {

DispatcherFrame frame = new DispatcherFrame();

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Render, new DispatcherOperationCallback(delegate(object parameter)

{

frame.Continue = false;

return null;

}), null);

Dispatcher.PushFrame(frame);

}

If my understanding of DispatcherPriority is correct, this will allow all render level messages to be processed, and will then return.

This feels a little like a WPF equivalent of Application.DoEvents, and I know their are dangers with that. Anybody with a deeper understanding of WPF threading got any thoughts on this?

Tuesday, June 09, 2009 5:57:05 PM UTC  #    Comments [0]    |  Trackback
 Friday, June 05, 2009
 Tuesday, June 02, 2009
Tuesday, June 02, 2009 6:05:49 PM UTC  #    Comments [0]    |   |  Trackback
 Friday, May 29, 2009

http://marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/

2 new features

- Support for Collection of binding to commands
- Support for Light weight Commands or as I call them Action

Friday, May 29, 2009 2:56:55 PM UTC  #    Comments [0]    |  Trackback
 Thursday, May 28, 2009

http://wpfwonderland.wordpress.com/2007/08/11/mixing-external-mergeddictionaries-with-local-resources-in-appxaml/

Adding local application resources

Even though it is easy to add external resources it’s likely that you’ll want to have a style or other resource that you don’t intend to shared across applications.  You could isolated these resources within a single page (Page.Resources) or element (DockPanel.Resources)  But what if you want to add  them to <Application.Resources> tag?  You can do it as long as you know the correct location. They have to go between the </ResourceDictionary.MergedDictionaries> and </ResourceDictionary> tags.

    <Application.Resources>
      <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="WorkshopHelpers/MainResources.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <!-- Place here...-->
        <Style TargetType="Rectangle" >
          <Setter Property="Width" Value="100"/>
          <Setter Property="Height" Value="80"/>
        </Style>
      </ResourceDictionary>
    </Application.Resources>
  </Application>

-Walt Ritscher

Thursday, May 28, 2009 5:25:41 PM UTC  #    Comments [0]    |  Trackback
  1: m_DispatcherTimer = new DispatcherTimer()
  2: {
  3: Interval = TimeSpan.FromSeconds(0.25),
  4: IsEnabled = true
  5: };
  6: 
  7: m_DispatcherTimer.Tick += delegate
  8: {
  9: CommandManager.InvalidateRequerySuggested();
 10: };
 11: 

http://robburke.net/2008/04/23/wpf-command-pattern-when-does-it-query-canexecute/

Thursday, May 28, 2009 5:47:02 AM UTC  #    Comments [0]    |  Trackback
 Tuesday, May 26, 2009
 Wednesday, May 13, 2009
 Thursday, May 07, 2009
 Wednesday, April 29, 2009
 Wednesday, April 15, 2009

MVVM Routed and Relay Command  http://stackoverflow.com/questions/650010/mvvm-routed-and-relay-command

MVVM in Silverlight 2 Apps http://msdn.microsoft.com/en-us/magazine/dd458800.aspx

[MVVM + Mediator + ACB = cool WPF App] http://marlongrech.wordpress.com/2009/04/08/mvvm-mediator-acb-cool-wpf-app-the-mvvm/

WPF & Silverlight Line of Business UI Design Pattern Home Page http://karlshifflett.wordpress.com/mvvm/   (*****)

Mediator v2 for MVVM WPF and Silverlight applications http://marlongrech.wordpress.com/2009/04/16/mediator-v2-for-mvvm-wpf-and-silverlight-applications/

CommandSink (Using RoutedCommands with a ViewModel in WPF) http://www.codeproject.com/KB/WPF/VMCommanding.aspx

Mapping commands in WPF http://www.codeproject.com/KB/WPF/MapperCommandBinding.aspx

From Josh Smith

“Use CommandSink if you must use routed commands. Otherwise, use RelayCommand. Routed commands should not be your first choice when choosing how to set up commanding, because it’s unnecessarily complicated and heavy for most use cases.”

 

Using Comand Binding to Enhance Any WPF Control http://www.dev102.com/2008/12/10/using-command-binding-to-enhance-any-wpf-control/

Wednesday, April 15, 2009 10:01:29 PM UTC  #    Comments [0]    |  Trackback
 Monday, March 02, 2009

http://www.tozon.info/blog/post/2009/02/16/Binding-to-Enums.aspx

I’ve seen numerous questions regarding data binding to Enums, together with many solutions on how to do it, but the question I’m asking myself is – do I really want to bind anything to an Enum?

I like to think about Enums purely as a coding aid – to help programmer code with some descriptive names instead of messing with pure numeric values. Similar to what constants are for, except Enums provide a set of values for describing a single parameter.

Instead of:

product.Quality = 3;

the programmer would write:

product.Quality = Quality.Good;

… providing that Quality Enum is declared something like:

public enum Quality
{
    JustBad, Poor, OK, Good, Excellent
}

Of course, you could set your enum values to some concrete numbers, like:

public enum Quality
{
    JustBad = 1, Poor = 2, OK = 3, Good = 4, Excellent = 5
}

… but in most cases you shouldn’t need to. Like I said, I see Enums only as a before-compilation, human <-> code communication, and therefore I believe no part of Enum should ever see the light of day (i.e. be exposed to the UI). And with that, there goes the need for binding to Enums…

Why would I want to bind to Enums anyway? Enum enumerators have no description (other than their names). If you need to provide spaces or even support localized descriptions, you’ll need to extend them significantly, so why not create a new class anyway? Here’s what I use instead of an Enum:

public sealed class Quality
{
    public const int JustBad = 1;
    public const int Poor = 2;
    public const int OK = 3;
    public const int Good = 4;
    public const int Excellent = 5;

    public Dictionary<int, string> Collection { get; private set; }

    public Quality()
    {
        Collection = new Dictionary<int, string>()
        {
            {JustBad,   "Just bad :("},
            {Poor,      "Poor"},
            {OK,        "OK"},
            {Good,      "Good"},
            {Excellent, "Excellent!"},
        };
    }
}

The programmer would still write:

product.Quality = Quality.Good;

so it makes it easy to refactor existing code. Additionally, you can put in any description for the values, support localization, and it’s easy bindable in Xaml - declare the class instance as a local resource:

<local:Quality x:Key="quality" />
and bind away:
<ListBox DisplayMemberPath="Value" 
         ItemsSource="{Binding Collection, Source={StaticResource quality}}" />
Monday, March 02, 2009 9:01:41 PM UTC  #    Comments [0]    |  Trackback
 Monday, February 02, 2009
 Friday, November 07, 2008

http://msdn.microsoft.com/en-us/ms741997(VS.85).aspx

        // Begins the storyboard.
        private void beginButton_Clicked(object sender, RoutedEventArgs args)
        {
            // Specifying "true" as the second Begin parameter
            // makes this storyboard controllable.
            myStoryboard.Begin(this, true);          
        
        }
        
        // Pauses the storyboard.
        private void pauseButton_Clicked(object sender, RoutedEventArgs args)
        {
             myStoryboard.Pause(this);          
        
        }
        
        // Resumes the storyboard.
        private void resumeButton_Clicked(object sender, RoutedEventArgs args)
        {
             myStoryboard.Resume(this);          
        
        }     
        
        // Advances the storyboard to its fill period.
        private void skipToFillButton_Clicked(object sender, RoutedEventArgs args)
        {
             myStoryboard.SkipToFill(this);          
        
        } 
        
        // Updates the storyboard's speed.
        private void setSpeedRatioButton_Clicked(object sender, RoutedEventArgs args)
        {
            // Makes the storyboard progress three times as fast as normal.
            myStoryboard.SetSpeedRatio(this, 3);          
        
        }           
        
        // Stops the storyboard.
        private void stopButton_Clicked(object sender, RoutedEventArgs args)
        {
             myStoryboard.Stop(this);          
        
        }         
Friday, November 07, 2008 3:48:14 PM UTC  #    Comments [0]    |  Trackback
 Tuesday, September 09, 2008
 Friday, August 15, 2008
 Friday, July 18, 2008
 Wednesday, July 16, 2008

To solve this, we have to manually add the mouse event handler onto the controls and set the handled parameter to true.

this.tbId.AddHandler(TextBox.MouseDownEvent, new RoutedEventHandler(tb_mouseDown), true);

Wednesday, July 16, 2008 10:06:03 PM UTC  #    Comments [0]    |  Trackback

_strandGroup = this.listViewGroups.SelectedItem as StrandGroup;

Wednesday, July 16, 2008 2:33:50 PM UTC  #    Comments [0]    |  Trackback

<GridViewColumn Header="Strand Type">
     <GridViewColumn.CellTemplate>
             <DataTemplate>
                    <ComboBox SelectedValue="{Binding Path=StrandId}" SelectedValuePath="Id" DisplayMemberPath="Name" Width="120" GotFocus="ComboBox_GotFocus" SelectionChanged="ComboBoxStrandType_SelectionChanged"
                                            ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LongitudinalStrandGroupsAssist}}, Path=MPrestressedStrands}"/>
             <DataTemplate>
     </GridViewColumn.CellTemplate>
</GridViewColumn>

Wednesday, July 16, 2008 2:32:24 PM UTC  #    Comments [0]    |  Trackback
 Wednesday, July 09, 2008
 Friday, June 20, 2008

From http://dotnet.org.za/rudi/archive/2008/03/25/10-things-i-didn-t-know-about-wpf-data-binding.aspx

 

1) Binding path "(TextBox.Text)" vs "Text"?

If you bind to a path called Text, WPF uses reflection to resolve the name. If you use the class-qualified name, binding avoids the reflection performance hit. Class-qualified names also allows binding to attached properties!

2) WPF doesn't raise exceptions to notify you about data binding problems

All binding errors are output as trace information and NOT exceptions!

Beatriz Costa (Who else) has a excellent article about this

3) Why use OneWayToSource binding mode?

Well, the target object must always be a DP! The most common use of OneWayToSource mode is to by-pass this restriction! The source doesn't need to be a DP and effectively using OneWayToSource reverses the binding direction.

A perfect example is Run, it's text property is not backed by a DP!

4) Default binding mode?

Not all DP's have the same default binding mode!!!

If the binding mode is two-way, but the CLR property that it is bound to is read-only... will cause problems! just keep in mind that you can't assume what the binding mode is!!!

It is always a good idea to explicitly specify your binding mode. Also remember that OneWay is slightly lighter than TwoWay!

5) RelativeSourceMode.PreviousData

If you bind to a collection of prices and need to show the change from the previous price to the current price then this little trick can be very useful... Pass the current item and the following binding into a IMultiValueConverter converter

{Binding RelativeSource={RelativeSource PreviousData}}

The multi value converter now just need to work out what the difference is!

6) RelativeSourceMode.FindAncestor

This is a very cool hack I found... Lets assume that you have a ListBox showing data. Normally if you have a TextBlock inside your DataTemplate and you don't supply it with a foreground color, then it would inherit the parents Foreground property. What is cool about this is that then when you click on the item, the font color would change from black to white! Now assume that your DataTemplate also contains a custom control that do not rely on the Foreground property to determine its color (As a example, I will use a Ellipse which has a Fill and not a Foreground/Background). If I add a Ellipse to this DataTemplate and  I do not set its fill, it would stay blank. Even if I give it a Fill color, it will fill with this color but if I now select this ListBox item, it will stay the provided color!

So how do I make my ellipse inherit the Foreground color and more importantly, how do I make it change to white once selected? Binding its Fill with the following

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=Foreground}

Now, it will inherit the parents Foreground and also change once selected...

7) Binding a ListBox to a custom object, What gets displayed in the ListBox?

When binding to a custom object, determining what is displayed in the ListBox can be one of 3 options

  1. Set the DisplayMemberPath on the ListBox to a path
  2. Create a DataTemplate
  3. Override the ToString() on the custom object. If no DisplayMemberPath or DataTemplate is found, the ToString() is called on the custom object.

8) {Binding Path=/}

Bind to the current item in the view! Just remember to set IsSynchronizedWithCurrentItem to true

[UPDATE] While reading Ian Griffiths blog, I found a entry detailing this behaviour in WPF databinding

9) Binding has a constructor that take Path as a parameter

This is just a small shortcut

{Binding Path=Name}

Can be written like this

{Binding Name}

10) {Binding}

This looks a little weird but all this means is that the source is defined somewhere up the tree... common place is Window.DataContext. By setting the DataContext to a collection, I can now add a ListBox to the visual tree and then binding this ListBox's ItemsSource to {Binding}. This will tell the ListBox that its ItemsSource is the DataContext of the Window!

Friday, June 20, 2008 5:39:03 PM UTC  #    Comments [0]    |  Trackback
 Tuesday, June 17, 2008
 Monday, June 02, 2008

http://geekswithblogs.net/thibbard/archive/2008/05/20/wpf---collectionviewsource-that-updates-automatically.aspx

public class AutoRefreshCollectionViewSource : CollectionViewSource
{
    protected override void OnSourceChanged(object oldSource, object newSource)
    {
        if (oldSource != null)
        {
            SubscribeSourceEvents(oldSource, true);
        }

        if (newSource != null)
        {
            SubscribeSourceEvents(newSource, false);
        }

        base.OnSourceChanged(oldSource, newSource);
    }


    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        bool refresh = false;
        foreach (SortDescription sort in SortDescriptions)
        {
            if (sort.PropertyName == e.PropertyName)
            {
                refresh = true;
                break;
            }
        }

        if (!refresh)
        {
            foreach (GroupDescription group in GroupDescriptions)
            {
                PropertyGroupDescription propertyGroup = group as PropertyGroupDescription;

                if (propertyGroup != null && propertyGroup.PropertyName == e.PropertyName)
                {
                    refresh = true;
                    break;
                }
            }
        }

        if (refresh)
        {
            View.Refresh();
        }
    }

    private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            SubscribeItemsEvents(e.NewItems, false);
        }

        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            SubscribeItemsEvents(e.OldItems, true);
        }
        else
        {
            // TODO: Support this
            Debug.Assert(false);
        }
    }

     
    private void SubscribeItemEvents(object item, bool remove)
    {
        INotifyPropertyChanged notify = item as INotifyPropertyChanged;     

        if (notify != null)
        {
            if (remove)
            {
                notify.PropertyChanged -= Item_PropertyChanged;
            }
            else
            {
                notify.PropertyChanged += Item_PropertyChanged;
            }
        }
    }
     
    private void SubscribeItemsEvents(IEnumerable items, bool remove)
    {
        foreach (object item in items)
        {
            SubscribeItemEvents(item, remove);
        }
    }

    private void SubscribeSourceEvents(object source, bool remove)
    {
        INotifyCollectionChanged notify = source as INotifyCollectionChanged;

        if (notify != null)
        {
            if (remove)
            {
                notify.CollectionChanged -= Source_CollectionChanged;
            }

            else
            {
                notify.CollectionChanged += Source_CollectionChanged;
            }
        }

         
        SubscribeItemsEvents((IEnumerable)source, remove);

    }

}

Using the CollectionViewSource is a good way of binding to a datasource and letting the XAML determine the sorting and grouping of the data. However, as your datasource changes, the grouping and sorting is not automatically "re-calculated", forcing your code to be smarter that it should be. I found a class today on MSDN forums that inherits from CollectionViewSource and adds automatic refresh capabilities. This code is smart enough to resort your items, regroup your items and even add new groupings as needed.
Some good CollectionViewSource links:

Monday, June 02, 2008 7:49:01 PM UTC  #    Comments [0]    |  Trackback
 Thursday, May 29, 2008
 Tuesday, May 27, 2008
 Wednesday, May 21, 2008
 Thursday, April 17, 2008

Databinding issue in WPF: with solution

http://www.lhotka.net/weblog/DataBindingIssueInWPFWithSolution.aspx#a89bf0c78-2bfc-4872-89b3-5499c4cbd0ae

(Important: set UpdateSourceTrigger to LostFocus for textbox)

Thursday, April 17, 2008 7:56:42 PM UTC  #    Comments [0]    |  Trackback
 Tuesday, April 15, 2008
 Tuesday, April 08, 2008

First, make sure the OpenHandCursor.cur file is marked as Resource (not EmbeddedResource) in the referenced assembly.

 

Code Block

 

// use resource in local assembly

// new Uri("pack://application:,,,/folder/filename.cur")

// use resource in referenced assembly

// new Uri("yourAssemblyName;component/folder/filename.cur"
// ,UriKind.Relative)

Stream cursorStream =

Application.GetResourceStream(new Uri    ("CursorLib;component/cursors/help.cur",
UriKind.Relative)).Stream;

this.Cursor = new Cursor(cursorStream);

Tuesday, April 08, 2008 6:11:08 PM UTC  #    Comments [0]    |  Trackback
 Wednesday, March 05, 2008
 Wednesday, February 27, 2008
 Friday, February 22, 2008
 Tuesday, February 19, 2008
 Friday, February 08, 2008
 Thursday, November 08, 2007

Following are some of my observations got from the book:

Chapter 1&2

  • XAML is just a way to use .NET APIs. WPF and XAML can be used independently from each other.
  • XAML specification defines rules that map .NET namespaces, types, properties, and events into XML namespaces, elements, and attributes.
  • Markup extensions are just classes with default constructors.
  • An object element can have three types of children: a value for a content property, collection items, or a value that can be type-converted to its parent.

Chapter 3 Important new Concepts in WPF

Logic Tree

The logical tree concept is straightforward, but why should you care about it? Because just about every aspect of WPF (properties, events, resources, and soon) has behavior tied to the logical tree. For example, property values are sometimes propagated down the tree to child elements automatically, and raised events can travel up or down the tree. Both of these behaviors are discussed later in this chapter.

Visual Tree
A similar concept to the logical tree is the visual tree. A visual tree is basically an expansion of a logical tree, in which nodes are broken down into their core visual components. Rather than leaving each element as a “black box,” a visual tree exposes the visual implementation details. For example, although a ListBox is logically a single control, its default visual representation is composed of more primitive WPF elements: a Border, two ScrollBars, and more.

Dependency Properties

A dependency property depends on multiple providers for determining its value at any
point in time. These providers could be an animation continuously changing its value, a
parent element whose property value trickles down to its children, and so on. Arguably
the biggest feature of a dependency property is its built-in ability to provide change notification.

Change Notification (Property Trigger)   

Property Value Inheritance

Multiple Providers

Attached Properties

Routed Events (routing Strategies:tunneling, bubbling, Direct)

Attached Events

Commands: a more abstract and loosely-coupled version of events.

 

image

Thursday, November 08, 2007 7:22:43 PM UTC  #    Comments [0]    |  Trackback
 Thursday, June 07, 2007
 Wednesday, June 06, 2007

I create this new category for studying WPF.

Wednesday, June 06, 2007 8:52:15 PM UTC  #    Comments [0]    |  Trackback
Copyright © 2010 Kevin Mocha. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: