Home Forums WPF controls Xceed DataGrid for WPF Can the content of a cell be a clickable link?

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #22695 |

    Is there a way to make one of the columns be a series of links?

    And then how would I hook up the event that would be executed when the user clicks on one of the cells (one of the links)?

    Please keep in mind that for now I just want to bind the datagridcontrol to a dataset I retrieve from a web service (so I’m now explicitly defining the columns in a ControlTemplate).

    Imported from legacy forums. Posted by Emmanuel (had 7131 views)

    Xceed Support
    Member
    Post count: 5658

    This can be done by placing a CellContentTemplate on the Column which is the “links” column.

    Here is a quick example of a CellContentTemplate:

    To be placed in a resource dictionary:

    <code>
    <DataTemplate x:Key=”myLinkTemplate”>
    <Hyperlink NavigateUri=”{Binding}” RequestNavigate=”OnRequestNavigate” />
    </DataTempalte>
    </code>

    Then, in the code behind for the resource dictionary where you defined this resource:

    <code>
    private void OnRequestNavigate ( object sender, RequestNavigateEventArgs e)
    {
    //Do whatever you want here…
    }
    </code>

    Imported from legacy forums. Posted by Marcus [Xceed] (had 506 views)

    User (Old forums)
    Member
    Post count: 23064

    Hi Marcus,

    Thanks for the fast reply and for letting me know this is possible, I really appreciate it!

    I’m trying to add the above DataTemplate to my resource dictionary, but I’m getting this error when trying to compile the project:

    ‘ResourceDictionary’ root element requires a x:Class attribute to support event handlers in the XAML file. Either remove the event handler for the RequestNavigate event, or add a x:Class attribute to the root element. Line 87 Position

    I tried adding an x:Class at the top of my resource dictionary XAML file but that didn’t work. I tried adding the above DataTemplate to a new resource dictionary within my window.resources, but that didn’t work. I guess I’m just not understanding how to use data template that have event handlers.

    Is there a full example I could look at that uses a DataTemplate with a RequestNavigate event handler (or any event handler)?

    Imported from legacy forums. Posted by Emmanuel (had 1415 views)

    User (Old forums)
    Member
    Post count: 23064

    For those wanting to do something similar, I ended up using a CellContentTemplate:

    <xcdg:DataGridControl.Columns>
    <xcdg:Column FieldName=”MyField”>
    <xcdg:Column.CellContentTemplate>
    <DataTemplate>
    <Button Content=”{Binding}” Click=”OnMyFieldClick”/>
    </DataTemplate>
    </xcdg:Column.CellContentTemplate>
    </xcdg:Column>
    </xcdg:DataGridControl.Columns>

    Sub OnMyFieldClick(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)
    MsgBox(“Yeah Baby!”)
    End Sub

    Place the <xcdg:DataGridControl.Columns> inside your <xcdg:DataGridControl>. I did a button instead of a link, since using <hyperlink> within the <datatemplate> here was giving me an error (something about inheriting a <FrameworkElement> for this to work).

    Imported from legacy forums. Posted by Emmanuel (had 514 views)

    User (Old forums)
    Member
    Post count: 23064

    The error mentioned in the previous post can be solved by surrounding the Hyperlink with a TextBlock (or any other relevant FrameworkElement descendant):

    <TextBlock>
    <Hyperlink NavigateUri=”{Binding Path=(prod:PageField.HRef), Mode=OneWay}” TargetName=”_blank”>
    <TextBlock Text=”{Binding Path=Name, Mode=OneWay}”/>
    </Hyperlink>
    </TextBlock>

    However, this produces a DataGrid Row error (which I consider a bug):

    Message: Unable to cast object of type ‘System.Windows.Documents.Hyperlink’ to type ‘System.Windows.Media.Visual’.
    Source: Xceed.Wpf.DataGrid
    at Xceed.Wpf.DataGrid.Row.OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
    at System.Windows.UIElement.RaiseIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs args)
    at System.Windows.FocusWithinProperty.FireNotifications(UIElement uie, ContentElement ce, Boolean oldValue)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState)
    at System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, DeferredElementTreeState& oldTreeState)
    at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
    at System.Windows.Input.KeyboardDevice.TryChangeFocus(DependencyObject newFocus, IKeyboardInputProvider keyboardInputProvider, Boolean askOld, Boolean askNew, Boolean forceToNullIfFailed)
    at System.Windows.Input.KeyboardDevice.Focus(DependencyObject focus, Boolean askOld, Boolean askNew)
    at System.Windows.Input.KeyboardDevice.Focus(IInputElement element)
    at System.Windows.ContentElement.Focus()
    at System.Windows.Documents.Hyperlink.OnMouseLeftButtonDown(MouseButtonEventArgs e)
    at System.Windows.ContentElement.OnMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e)
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
    at System.Windows.ContentElement.ReRaiseEventAs(RoutedEventArgs args, RoutedEvent newEvent)
    at System.Windows.ContentElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
    at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
    at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
    at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
    at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
    at System.Windows.UIElement.RaiseEventImpl(RoutedEventArgs args)
    at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
    at System.Windows.Input.InputManager.ProcessStagingArea()
    at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
    at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
    at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
    at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

    Imported from legacy forums. Posted by Nelis (had 750 views)

    User (Old forums)
    Member
    Post count: 23064

    Getting the same Error….it MUST be a bug as I have a Hyperlink in a normal TextBlock (outside of a grid) and it performs perfectly.

    Imported from legacy forums. Posted by Desmond (had 536 views)

    Xceed Support
    Member
    Post count: 5658

    I have confirmed that this is an issue and haved added a case. You will be notified when it is corrected.

    Imported from legacy forums. Posted by Jenny [Xceed] (had 396 views)

    User (Old forums)
    Member
    Post count: 23064

    Thanks Jenny…all we are left to use in place of a Hyperlink is a Button which looks a bit cumbersome ..unless somebody has a nice Content Control to make a Button look like Link 😉

    Cheers,

    Dezzz.

    Imported from legacy forums. Posted by Desmond (had 696 views)

    Xceed Support
    Member
    Post count: 5658

    You can try this (I didn’t put the required navigation code in)

    <code>
    <xcdg:Column.CellContentTemplate>
    <DataTemplate>
    <TextBlock>
    <Underline>
    <local:BindableRun BindableText=”{Binding}”/>
    </Underline>
    </TextBlock>
    </DataTemplate>
    </xcdg:Column.CellContentTemplate>
    </code>

    If you want the code for the “binadable run”:

    <code>
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Documents;
    using System.Windows;

    namespace Xceed.Wpf.Documentation
    {
    class BindableRun : Run
    {
    public BindableRun()
    :base()
    {
    }

    public static string GetBindableText( DependencyObject obj )
    {
    return ( string )obj.GetValue( BindableTextProperty );
    }

    public static void SetBindableText( DependencyObject obj, string value )
    {
    obj.SetValue( BindableTextProperty, value );
    }

    public static readonly DependencyProperty BindableTextProperty =
    DependencyProperty.Register( “BindableText”, typeof( string ), typeof( BindableRun ), new UIPropertyMetadata( null, BindableTextProperty_PropertyChanged ) );

    private static void BindableTextProperty_PropertyChanged(
    DependencyObject dependencyObject,
    DependencyPropertyChangedEventArgs e )
    {
    if( dependencyObject is Run )
    {
    ( ( Run )dependencyObject ).Text = ( string )e.NewValue;
    }
    }
    }
    }

    </code>

    Imported from legacy forums. Posted by Jenny [Xceed] (had 525 views)

    User (Old forums)
    Member
    Post count: 23064

    Hey..now that’s a service,,,Many thanks !!!

    Cheers,

    Dezzz.

    Imported from legacy forums. Posted by Desmond (had 474 views)

    Xceed Support
    Member
    Post count: 5658

    My pleasure 🙂

    Imported from legacy forums. Posted by Jenny [Xceed] (had 7631 views)

Viewing 11 posts - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.