Wednesday, October 12, 2016

MVVM: DataGridComboBoxColumn binding doesn't pick data

This is not a new problem, but I faced this recently. The WPF DataGrid control has DataGridComboBoxColumn which, when bound to a viewmodel collection, doesn't pick up the data.

Here is the viewmodels I created for the demo app.

And the types of the properties are:

    public class MainViewModel : ViewModel
    {
        ObservableCollection<PersonViewModel> _Data;
        ...

    public class PersonViewModel : ViewModel
    {
        string _Name;
        int _Age;
        PersonViewModel _SelectedSibling;
        ObservableCollection<PersonViewModel> _Siblings;
        ...

The binding would seem innocuous, but it doesn't work.
        <DataGrid AutoGenerateColumns="False"
                  ItemsSource="{Binding Data}">
            <DataGrid.Columns>
                ...
                <DataGridComboBoxColumn DisplayMemberPath="Name"
                                        Header="Siblings"
                                        ItemsSource="{Binding Siblings}"
                                        SelectedItemBinding="{Binding SelectedSibling}">
                </DataGridComboBoxColumn>
                ...
            </DataGrid.Columns>
        </DataGrid>


You would expect the combobox to be filled with the names of the siblings, but it doesn't.

So, I looked up and found the answer on StackOverflow:
DataGridColumn doesn't derive from FrameworkElement or FrameworkContentElement so it isn't in the visual tree and doesn't have a DataContext and that's why your binding is failing.
That means the binding on the column's ItemsSource itself won't work. We need to access the combobox in the column and create the binding there.

Here is the working XAML code:

        <DataGrid AutoGenerateColumns="False"
                  ItemsSource="{Binding Data}">
            <DataGrid.Columns>
                ...
                <DataGridComboBoxColumn DisplayMemberPath="Name"
                                        Header="Siblings"
                                        ItemsSource="{Binding Siblings}"
                                        SelectedItemBinding="{Binding SelectedSibling}">
                    <DataGridComboBoxColumn.ElementStyle>
                        <Style TargetType="{x:Type ComboBox}">
                            <Setter Property="ItemsSource" Value="{Binding Siblings}" />
                        </Style>
                    </DataGridComboBoxColumn.ElementStyle>
                    <DataGridComboBoxColumn.EditingElementStyle>
                        <Style TargetType="{x:Type ComboBox}">
                            <Setter Property="ItemsSource" Value="{Binding Siblings}" />
                        </Style>
                    </DataGridComboBoxColumn.EditingElementStyle>
                </DataGridComboBoxColumn>
                ...
            </DataGrid.Columns>
        </DataGrid>

And now, we get the desired output:

Tuesday, September 24, 2013

My Codeproject Article On WPF DataGrid Custom Header With Filter

Woohoo! My first ever article on Codeproject has been published. Here is the URL:
http://www.codeproject.com/Articles/657657/WPF-DataGrid-With-Excel-Style-Column-Filter

This article has been based on a journey to find simple UI designs. More about them in coming up articles.

It took me 3 weeks to understand WPF DataGrid. It was faster near the end, when I started using Snoop. We can do really good UI designing with WPF. But sadly, most of the professional apps are still not ready to change to simpler UI. Too simple for them, maybe? :-P

Thanks for reading this post! And, yes, please, do vote on Codeproject article, if it makes sense to you.

Saturday, September 15, 2012

Auto Save in Paint - ver 1.7.0.2 - Patch Release

This is a small post to post a minor patch on top of release version 1.7

Tflamb noticed that on Windows 7, the XP Paint application was not able to save the JPEG files, and thus shrink them. He suggested a delay to be introduced while saving the files.

I made the delay configurable in the "Options".

Enhancement:
1. In "Options" dialog box, there is a number selector (numeric up/down box) for the required delay while Paint application saves a file. The value that it can hold is in the range of 0 to 30. This number is the delay in seconds that AutoSavePaint (ASP) will wait for Paint application to save per file. If the delay is 0, then ASP will behave normally and no extra delay will be introduced.

I'm only uploading the binary+source for the patch, instead of the whole package. Please download ver 1.7 first and then apply the patch.

Download links for Auto Save in Paint v1.7.0.2 patch:
Binary
Source

Thursday, November 3, 2011

Non intrusive shadow effect for translucent area

NeXXeuS asked a very interesting question. In WPF, you have DropShadowEffect which displays a shadow of a geometry/shape. But if the geometry/shape is translucent (0 < Opacity < 1),  then you can see the shadow through.


The question was posted on SO as:


Ques: I have a DropShadowEffect on a Rectangle with a fill that's slightly transparent. The problem is, the drop shadow also shows up inside the fill, which is what I don't want. Anyways to solve this? I tried this, but it doesn't work for me.

My answer:
This is very tricky. You need to customize the shadow effect for this. This solution gives the desired effect.
This is a sample Grid with yellow background. I've drawn two intersecting rectangles of 100x100 dimension on it. You may need to customize the size according to your need. One rectangle is gray rectangle (to show shadow), and the other is a red rectangle (the actual semi-transparent rectangle that you want to display). The shadow depth has been hard coded as 5 pixels here. Please customize it at:
  • RectangleGeometry Rect="5,5,100,100"
  • RectangleGeometry Rect="0,0,95,95"
So, the grid looks like:
   1:  <Grid Background="Yellow">
   2:      <!-- A rectangle for shadow -->
   3:      <Rectangle Fill="Gray" Width="100" Height="100" Opacity=".7">
   4:          <Rectangle.Clip>
   5:              <CombinedGeometry GeometryCombineMode="Exclude">
   6:                  <CombinedGeometry.Geometry1>
   7:                      <RectangleGeometry Rect="5,5,100,100"/>
   8:                  </CombinedGeometry.Geometry1>
   9:                  <CombinedGeometry.Geometry2>
  10:                      <RectangleGeometry Rect="0,0,95,95"/>
  11:                  </CombinedGeometry.Geometry2>
  12:              </CombinedGeometry>
  13:          </Rectangle.Clip>
  14:          <Rectangle.Effect>
  15:              <!-- For nice soft shadow effect -->
  16:              <BlurEffect Radius="5" />
  17:          </Rectangle.Effect>
  18:      </Rectangle>
  19:   
  20:      <!-- Actual rectangle which is translucent -->
  21:      <Rectangle Fill="Red" Width="100" Height="100" Opacity=".6" >
  22:          <Rectangle.Clip>
  23:              <RectangleGeometry Rect="0,0,95,95"/>
  24:          </Rectangle.Clip>
  25:      </Rectangle>
  26:  </Grid>

Hope this is interesting to you as much as I had fun creating it! :)

Saturday, October 1, 2011

Visio 2010 64-bit bummer

Its so weird and irritating to know something doesn't work and has been documented already. Just that I did not search for it. How would anyone know if things will work or not?

You cannot use the ActiveX control of Visio 64 bit edition in your VS applications. I happen to run everything in 64 bit mode. x-(

Here is the info: http://support.microsoft.com/kb/980533

You cannot add the Microsoft Visio 14.0 drawing control to a Windows Form application in Visual Studio if you have the 64-bit version of Visio 2010 installed

Cause: These problems occur because the Visual Studio designer does not support 64-bit ActiveX controls and because the 64-bit version of Visio 2010 only works with the 64-bit version of the Microsoft Office Visio 14.0 drawing control. Therefore, the drawing control cannot be instantiated.


To work around this problem, follow these steps:
  1. Install the 32-bit version of Visio 2010 on a computer....

Ridiculous. Now, I've to undo the installation and install 32 bit version. Great! :(
Why is VS Designer not modified to support 64 bit ActiveX controls?

Update:
Even when I uninstalled 64 bit Visio, the 32 bit Viso won't install because of 64 bit Office installed on my machine. That means I've to uninstall whole 64 bit MS Office for just one VS Designer to work. WTH?!