WPF DataGrid sample: Add a preview ToolTip to a ScrollViewer


A customer was asking for a sample of a preview ToolTip on scrolling for the DataGrid and Ben Carter, one of our awesome Devs, wrote a sample here for any general ItemsControl.  If you haven’t already, you can download the binaries and source for the DataGrid hereWith Ben’s sample I’ve put it to use in the DataGrid.  Pretty much all the work has already been done by Ben’s code, I just use the attached behavior he has defined.  I have one DataGrid that has a preview ToolTip similar to his ListBox example and one DataGrid that has a preview ToolTip with the item count.  I’ve also included a checkbox for changing the scrolling mode from live to defered (more on defered scrolling here).  Check out the DataGrid sample here.


dataGridWithScrollPreview


 

DataGrid_V1_ScrollPreviewSample.zip

Comments (19)

  1. Alexander says:

    Hi Vince,

    a great thing! I am deeply impressed that dynamically selecting a picture in a cell is far less complicated than i feared it was 😉

    But I have some worries remaining:

    *) Can I somehow tell a DataGridComboboxColumn to show "Vanilla (organic production)" and to read/save "vanilla_organic" (for localization purposes, for example)? i.e. like the DisplayMemberPath/SelectedValuePath-Property of a standard ComboBox?

    *) Is it possible to tell my Column that it should display the DisplayName-Attribute Value of the Property of the Object it is bound to? (Sounds strange, I know, but would make a superb clean solution)

    Great work you do!

    Alex

  2. vinsibal says:

    1. DataGridComboBoxColumn.DataFieldTarget might be what you’re looking for.  There are actually some tricky things going on here so I’m actually going to do a post on this.  stay tuned.

    2. I’m assuming you mean the ColumnHeader display name right?  If you are doing auto-column generation you can do something like this:

          [DisplayName("PersonID")]

           public int Id

           {

               get { return id; }

               set

               {

                   id = value;

                   OnPropertyChanged("Id");

               }

           }

               this.DataGrid_Standard.AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGrid_Standard_AutoGeneratingColumn);

    void DataGrid_Standard_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)

           {

               e.Column.Header = (e.PropertyDescriptor as MemberDescriptor).DisplayName;

           }

    Then your headers will all take on the DisplayName attribute values.

  3. Sandeep (India) says:

    Hi,

    We are very much impressed by features of this datagrid. We are looking for more features like:

    1. Summary Footer

    2. Custom Formula in datagrid and footer

    3. Save Layout

    4. Extended Filter

    5. Export to excel, pdf, csv, xps

    6. Conditional Formatting

    7. drag and drop rows (within and from other grid)

    8. Merge cells in Header / Footer / Body.

    I would appreciate your reply.

    Regards,

    Sandeep

  4. vinsibal says:

    I’ve consolidated your asks from both posts here.  Note that even if we don’t plan to support some of these features out of the box, WPF and the DataGrid control have an extensible design to easily support many of these scenarios.

    1. Summary Footer

    [Vince]: Will not be supported out of the box.  If you can be a little more specific on your requirements maybe I can provide you a sample of this feature.

    2. Custom Formula in datagrid and footer

    [Vince]: Will not be supported out of the box.

    3. Save DataGrid Layout

    [Vince]: Will not be supported out of the box.

    4. Extended Filter, Data Filtering (single/multi column)

    [Vince]: Will not be supported out of the box.  This can be accomplished at different levels.  You can use the CollectionViewSource, linq, etc.

    5. Column Customization (To hide a column User can drag column to an area or on right click of a column give option to hide column)

    [Vince]: hidden columns will be supported in the RTM version.

    6. Export to excel, pdf, csv, xps

    [Vince]: CSV is supported but you have to go through CopyingRowClipboardContent to add support for other formats.  

    7. Conditional Formatting

    [Vince]: Already supported through Binding.StringFormat as well as Converters.

    8. drag and drop rows (within and from other grid)

    [Vince]: Ben Carter wrote a sample on this which will be up shortly.  

    9. Merge cells in Header / Footer / Body.

    [Vince]: Will not be supported out of the box.  This is a tougher one to extend and we are looking into this for future release.

  5. As you might have heard, .NET Framework 3.5 SP1 and Visual Studio 2008 SP1 are out today! There are a

  6. Overview The DataGrid uses a set of DataGridColumns to describe how to display its data just like a GridView

  7. In the v1 release (and CTP) of the WPF DataGrid there will be support for Clipboard.Copy but no support

  8. Here is a short sample on how to create a tri-state sorting experience with the WPF DataGrid . In the

  9. There have been several questions on the WPF CodePlex discussion list relating to styling rows and columns

  10. vamsi says:

    i need to drag column from postion to other in wpf datagrid.is it possible

  11. vinsibal says:

    vamsi,

    That functionality should be working by default.  Have you tried it?

  12. Steve Lloyd says:

    Hi, I wonder if you can help me.

    I have a memory leak when refreshing the Data on a DataGFid, I’m guessing that I am not releasing something properly but I cannot see what it is.

    As a test I replaced your initilaization code with:

    public Window1()

           {

               InitializeComponent();

               DataGrid_Standard.Columns.CollectionChanged += new NotifyCollectionChangedEventHandler(Columns_CollectionChanged);

               // update config bindings

               ICollectionView view = CollectionViewSource.GetDefaultView(DataGrid_Standard.ItemsSource);

               iecv = (IEditableCollectionView)view;

               this.NewItemPlaceholderPositionCB.DataContext = iecv;

               System.Timers.Timer t = new System.Timers.Timer(1000);

               t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);

               t.Start();

           }

    and added a handler of:

    void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

           {

               //throw new NotImplementedException();

               DataGrid_Standard.Dispatcher.Invoke((Action)delegate()

               {

                   DataGrid_Standard.ItemsSource = new EditablePeople(20);

               });

           }

    When you run this you can see the memory getting chewed up on each refresh.

    Do you have any pointer/suggestions to prevent this from happening?

    Thanks in advance for any help.

    Steve

  13. vinsibal says:

    Hi Steve,

    I ran it through windbg and found that each Person lives on the heap through a short-lived short handle.  Here is the output from doing a gcroot on one of the Person objects:

    0:022> !gcroot -nostacks 00000000048f8730

    DOMAIN(00000000004BB4A0):HANDLE(WeakSh):3e1528:Root:0000000002b25ab8(MS.Win32.HwndWrapperHook)->

    0000000002b25990(MS.Win32.HwndWrapper)->

    0000000002b249f0(System.Windows.Threading.Dispatcher)->

    0000000002b49c50(System.Windows.Input.InputManager)->

    0000000002b4a7a8(System.Windows.Input.StylusLogic)->

    0000000002b4a9a0(System.Collections.Generic.Dictionary`2[[System.Object, mscorlib],[System.Windows.Input.PenContexts, PresentationCore]])->

    0000000002b4aa20(System.Collections.Generic.Dictionary`2+Entry[[System.Object, mscorlib],[System.Windows.Input.PenContexts, PresentationCore]][])->

    0000000002d6c848(System.Windows.Interop.HwndSource)->

    0000000002bed178(DataGridCTPSample.DataGridBasicSample_Demo2)->

    0000000002bf9300(Microsoft.Windows.Controls.DataGrid)->

    00000000048be620(DataGridCTPSample.People)->

    00000000048be790(System.Collections.Generic.List`1[[DataGridCTPSample.Person, DataGridCTPSample]])->

    00000000048e15c0(System.Object[])->

    00000000048f8730(DataGridCTPSample.Person)

    Since the reference isn’t a strong handle or isn’t pinned I tried to see if it just wasn’t getting collected early enough and that is the reason.  Try adding the GC.Collects to the code above and you’ll find the heap does not explode.

    void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

           {

               //throw new NotImplementedException();

               DataGrid_Standard.Dispatcher.Invoke((Action)delegate()

               {

                   DataGrid_Standard.ItemsSource = new People(20);

               });

               GC.Collect();

               GC.WaitForPendingFinalizers();

               GC.Collect();

           }

  14. Trey says:

    Vincent-

    I’m looking to filter the displayed items in my datagrid using 3 check boxes that are specific to enum values representing my object’s state.

    Basically the row (my business object) is either InProcess, Finalized, Archived. And I would like to include a checkbox for each one that allows the user to include them or exclude them from the display.

    I am using MVVM which is what makes it tricky considering all the examples I have seen are using a text box changed evant to filter certain items from the code-behind of the view.

    Any thoughts or examples you know of that might help me?

    These check boxes basically need to filter an OC on my view model I think is the best way to do it. But the code needs to be in the VM… can I bind checkboxes to commands?

    -T

  15. vinsibal says:

    Trey,

    Please take a look at this thread, http://wpf.codeplex.com/Thread/View.aspx?ThreadId=63315.

  16. saru says:

    hi,

    this is very useful for me. Thanks for sharing ur ideas.I have a problem with adding DatagridTemplate column with Image dynamically i coded like this but its not working.can u suggest any better approach :

    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Image));

               Binding b = new Binding("Image");            

               factory.SetValue(Image.SourceProperty, b);

               DataTemplate cellEditingTemplate = new DataTemplate();

               cellEditingTemplate.VisualTree = factory;

               DataGridTemplateColumn imageColumn = new DataGridTemplateColumn();

               imageColumn.Header = "Image";            

               imageColumn.CellEditingTemplate = cellEditingTemplate;

               dgDynamicColumns.Columns.Add(imageColumn);

    If at all i tried this for DataPicker its working fine but for Image it is failing to display a Image in the Column.

    How to Show Image column in the Datagrid from code.

    Thanks in Advance,

    Saru