Wpf: Missing something simple?

Wpf: Missing something simple?

Old forum URL: forums.lhotka.net/forums/t/8568.aspx


ajj3085 posted on Tuesday, February 23, 2010

Ok, I'm finally trying the MVVM stuff in a Wpf client application (not SL).

This is what I'd like:  I have an OpenDocument method on my VM.

I want to fire the Open command when a row is double clicked in my DataGrid, passing the DocumentInfo object as a command parameter.

I can't figure this out!

Any ideas?

(also, whats the diff between Interaction.Triggers in Interactivity and normal Wpf triggers?)

triplea replied on Wednesday, February 24, 2010

Hi Andy

I use the grid from the WPF toolkit so in XAML:

<

 

 

dg:DataGrid x:Name="MyGrid" ItemsSource="{Binding Path=Model}" csla:InvokeMethod.TriggerEvent="MouseDoubleClick" csla:InvokeMethod.MethodName="SomethingSelected">

In the VM:

public void SomethingSelected(object sender, Csla.Wpf.ExecuteEventArgs e)
{
   
var source = ((MouseButtonEventArgs)e.TriggerParameter).OriginalSource as DependencyObject;
   
var row = MyApp.Infrastructure.UIHelper.TryFindParent<Microsoft.Windows.Controls.DataGridRow>(source);

   
if (row != null)
    {
        var item =
.row.DataContext as MyObj;
        ...
    }
}

The UI helper method I found from the net but I cannot find the bookmark for it. Instead I have blatantly pasted the code below.

using System.Windows
using
System.Windows.Media
 

namespace MyApp.Infrastructure
{
  public
static class
UIHelper
 
{
   
///
<summary>
    ///
Finds a parent of a given item on the visual tree.
    ///
</summary>
    /// <typeparam name="T">The type of the queried item.
</typeparam>
   
/// <param name="child">
A direct or indirect child of the
   
/// queried item.
</param>
   
/// <returns>
The first parent item that matches the submitted
   
///
type parameter. If not matching item can be found, a null
   
/// reference is being returned.
</returns>
   
public
static T TryFindParent<T>(this DependencyObject child) where T :
DependencyObject
   
{
      
//get parent item
     
DependencyObject parentObject = GetParentObject(child
);

      //we've reached the end of the tree
      
if
(parentObject == null) return null
;

      //check if the parent matches the type we're looking for
      T parent = parentObject as T
;

      if (parent != null)
      {
       
return
parent
;
      }
     
else
     
{
        
//use recursion to proceed with next level
       
return
TryFindParent<T>(parentObject
);
      }
   }
 

  /// <summary>
  ///
This method is an alternative to WPF's
  /// <see cref="VisualTreeHelper.GetParent"/>
method, which also
  ///
supports content elements. Keep in mind that for content element,
  ///
this method falls back to the logical tree of the element!
  ///
</summary>
  /// <param name="child">The item to be processed.
</param>
  /// <returns>
The submitted item's parent, if available. Otherwise
  /// null.
</returns>
 
public
static DependencyObject GetParentObject(this DependencyObject child
)
  {
   
if
(child == null) return null
;

    //handle content elements separately
   
ContentElement contentElement = child as ContentElement
;

    if (contentElement != null)
    {
     
DependencyObject parent = ContentOperations.GetParent(contentElement
); 

      if
(
parent != null) return parent
; 

      FrameworkContentElement
fce = contentElement as FrameworkContentElement
; 

      return
fce != null ? fce.Parent : null
;
    }

    //also try searching for parent in framework elements (such as DockPanel, etc)
    FrameworkElement frameworkElement = child as FrameworkElement
;

    if (frameworkElement != null)
    {
     
DependencyObject parent = frameworkElement.Parent
; 
      if
(
parent != null) return parent
;
    }

    //if it's not a ContentElement/FrameworkElement, rely on VisualTreeHelper
   
return
VisualTreeHelper.GetParent(child
);
  }
}

ajj3085 replied on Wednesday, February 24, 2010

Great, thanks for the tip!  I wasn't sure if InvokeMethod or the Execute class was the one to use.  I used this code though to get the row I wanted, seems simplier to me:

 

 

 

 

 

 

 

 

 

public static class Extensions {

 

 

 

public static T GetParentElement<T>( this DependencyObject element ) where T : DependencyObject {

T result =

 

null;

 

 

 

if ( element is T ) {

result = (T)element;

}

 

 

 

else if ( element != null ) {

result = GetParentElement<T>(

 

VisualTreeHelper.GetParent( element ) );

}

 

 

 

return result;

}

}

Which i used like this:

var gridRow = source.GetParentElement<DataGridRow>();

triplea replied on Wednesday, February 24, 2010

Thanks for that, its more readable and elegant.

ajj3085 replied on Wednesday, February 24, 2010

Sadly it doesn't end up very readable on the forum...

Copyright (c) Marimer LLC