RadButton cell in RadTreeListView column doesn't react on bound command (the command doesn't fire).)

8 posts, 1 answers
  1. Yaroslav
    Yaroslav avatar
    122 posts
    Member since:
    Jan 2016

    Posted 20 Jul Link to this post

    Hi. I write C# WPF MVVM Prism 6 application. I'm interested in RadTreeListView with buttons-column there. I defined the folowing XAML for buttons-column in RadTreeListView:

    <telerik:RadTreeListView x:Name="Hierarchical" Grid.Row="2" Grid.Column="0" AutoGenerateColumns="False" AutoExpandItems="True" IsSynchronizedWithCurrentItem="True"
                                         CanUserReorderColumns="False" CanUserSortColumns="False" CanUserSortGroups="False" CanUserDeleteRows="False" CanUserInsertRows="False"
                                         IsFilteringAllowed="False" EnableLostFocusSelectedState="False" RowIndicatorVisibility="Collapsed" SelectionUnit="FullRow"
                                         ItemsSource="{Binding DeviceProfile}" Visibility="{Binding AreRegistersInHierarchyVisible}" SelectedItem="{Binding SelectedProfileElement}"
                                         >
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
                 <!--Button-column "Read current value from outer device selected register"-->
           <telerik:GridViewDataColumn IsVisible="{Binding IsReadColumnButtonVisible}">
               <telerik:GridViewDataColumn.CellTemplate>
                   <DataTemplate>
                      <telerik:RadButton Margin="5" Content="Read Register Current Value" Visibility="{Binding IsSelected,
                                        RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource booleanToVisibilityConverter}}"
                                                       Command="{Binding InitializeRegisterCurrentValueReadingCommand}"/>
                   </DataTemplate>
               </telerik:GridViewDataColumn.CellTemplate>
          </telerik:GridViewDataColumn>
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
    </telerik:RadTreeListView>

    I use your BooleanToVisibilityConverter in Prism UserControl where the RadTreeListView is:

    <UserControl.Resources>
            <telerik:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
    </UserControl.Resources>

    Below is the source code of 'InitializeRegisterCurrentValueReadingCommand' command that is in View Model to which the Prism UserControl binds to:

    // The command definition.
    public DelegateCommand<object> InitializeRegisterCurrentValueReadingCommand { get; private set; }
     
    // The command logic method.
    private void initializeRegisterValueReading(object parameter)
    {
        // My custom C# code
    }
     
    // The command CanExecute method.
    private bool initializeRegisterValueReadingCanExecute(object parameter)
    {
       // Some bolean condition is.
    }
     
    // Here is creating of command inside View Model constructor.
    this.InitializeRegisterCurrentValueReadingCommand = new DelegateCommand<object>(this.initializeRegisterValueReading, this.initializeRegisterValueReadingCanExecute);

    Please see the screnshot in 'RadTreeListView_with_buttons.PNG' file attached. Where "Прочитать значение из регистра" button is "Read Register Value" button and "Записать значение в регистр" button is "Write Value To Register" button. "InitializeRegisterCurrentValueReadingCommand' command is bound to "Read Register Value" button. But when I pess (click) this button the command doesn't fire! I also tryed the following notation in XAML:

    <telerik:EventToCommandBehavior.EventBindings>
         <telerik:EventBinding
             Command="{Binding InitializeRegisterCurrentValueReadingCommand}"
             EventName="Click"
             PassEventArgsToCommand="True"/>
    </telerik:EventToCommandBehavior.EventBindings>

    But the result was the same pitiable-bad. But interestingly, when I create the handler of ButtonClick event (for button-cell) in code-behind, the the handler fires when the button is clicked! But  my application is pure MVVM application! So how do I make the command fire when user clicks the button? Either with such markup:

    <telerik:GridViewDataColumn IsVisible="{Binding IsReadColumnButtonVisible}">
                            <telerik:GridViewDataColumn.CellTemplate>
                                <DataTemplate>
                                    <telerik:RadButton Margin="5" Content="Прочитать значение из регистра" Visibility="{Binding IsSelected,
                                        RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource booleanToVisibilityConverter}}"
                                                       Command="{Binding InitializeRegisterCurrentValueReadingCommand}"/>
                                </DataTemplate>
                            </telerik:GridViewDataColumn.CellTemplate>
                        </telerik:GridViewDataColumn>

    or with such markup:

    <telerik:GridViewDataColumn IsVisible="{Binding IsReadColumnButtonVisible}">
                            <telerik:GridViewDataColumn.CellTemplate>
                                <DataTemplate>
                                    <telerik:RadButton Margin="5" Content="Прочитать значение из регистра" Visibility="{Binding IsSelected,
                                        RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource booleanToVisibilityConverter}}">
                                        <telerik:EventToCommandBehavior.EventBindings>
                                            <telerik:EventBinding
                                                Command="{Binding InitializeRegisterCurrentValueReadingCommand}"
                                                EventName="Click"
                                                PassEventArgsToCommand="True"/>
                                        </telerik:EventToCommandBehavior.EventBindings>
                                    </telerik:RadButton>
                                </DataTemplate>
                            </telerik:GridViewDataColumn.CellTemplate>
                        </telerik:GridViewDataColumn>

    How do I make the command fire when user clicks the button? Please help solve the problem. Thank you very much in advance.

  2. Martin Vatev
    Admin
    Martin Vatev avatar
    87 posts

    Posted 25 Jul Link to this post

    Hi Yaroslav,

    May I ask you to perform a simple test - expose your ViewModel as a resource and use it a Source of the binding:
    <UserControl.Resources>
            <telerik:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
        <local:ViewModel x:Key="myViewModel"/>
    </UserControl.Resources>
    ...
    ...
    <telerik:GridViewDataColumn IsVisible="{Binding IsReadColumnButtonVisible}">
               <telerik:GridViewDataColumn.CellTemplate>
                   <DataTemplate>
                      <telerik:RadButton Margin="5" Content="Read Register Current Value" Visibility="{Binding IsSelected,
                                        RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource booleanToVisibilityConverter}}"
                                                       Command="{Binding InitializeRegisterCurrentValueReadingCommand, Source={StaticResource myViewModel}}"/>
                   </DataTemplate>
               </telerik:GridViewDataColumn.CellTemplate>
          </telerik:GridViewDataColumn>

    Please give it a try and let me know how it works for you.

    Regards,
    Martin Vatev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Yaroslav
    Yaroslav avatar
    122 posts
    Member since:
    Jan 2016

    Posted 25 Jul in reply to Martin Vatev Link to this post

    Hello, Martin. I can't do in your way. Because xmlns local: is already used. Please see:

    <UserControl x:Class="DeviceParameters.Views.DeviceParametersView"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:prism="http://prismlibrary.com/"            
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 xmlns:local="clr-namespace:DeviceParameters"
                 prism:ViewModelLocator.AutoWireViewModel="True">

    So i tryed to use the folowing:

    xmlns:vm="clr-namespace:DeviceParameters.ViewModels"

    Just below xmlns:local. Please see:

    <UserControl x:Class="DeviceParameters.Views.DeviceParametersView"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:prism="http://prismlibrary.com/"            
                 xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                 xmlns:local="clr-namespace:DeviceParameters"
                 xmlns:vm="clr-namespace:DeviceParameters.ViewModels"
                 prism:ViewModelLocator.AutoWireViewModel="True">

    But when I try to type:

    <UserControl.Resources>
       <telerik:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
       <vm:DeviceParametersViewModel  x:Key="myViewModel"/>
    </UserControl.Resources>

    then the line

    <vm:DeviceParametersViewModel  x:Key="myViewModel"/>

     is emphasized with the blue wavy line with the folowing error mesage:  "DeviceParametersViewModel type does not include any available constructors".

    Below I present full definition of DeviceParametersViewModel constructor:

    public class DeviceParametersViewModel : BindableBase, IConfirmNavigationRequest
    {
    . . . . . . . . . . . . .
     
    public DeviceParametersViewModel(IEventAggregator eventAggregator, IConnectionService connectionService)
    {
        // Looslely coopled events service.
        this._eventAggregator = eventAggregator;
        // My custom shared service.
        this._connectionService = connectionService;
        this._connectionService.RegisterDataRead += _connectionService_RegisterDataRead;
        // Initially register searching parameter is empty.
        this.RegisterSearchText = string.Empty;
        // Support for modal <OK> dialogs.
        this.NotificationRequest = new InteractionRequest<INotification>();
        // Register searching mode "By adress" is default register searching mode.
        this.RegisterSearchingMode = RegisterSearchMode.SearchByAddress;
        // By default the hierarchical registers colection is displayed.
        this.AreRegistersInHierarchyVisible = Visibility.Visible;
        // Planar register colection is hidden.
        this.AreRegistersInPlanarVisible = Visibility.Hidden;
        this.SelectedProfileElement = new object();
        // These two properties are attracting on each column-button visibility.
        this.IsReadColumnButtonVisible = true;
        this.IsWriteColumnButtonVisible = true;
        // Initialization of command:
        this.HandleProfileElementSelectionChangedCommand = new DelegateCommand<object>(this.handleProfileElementSelectionChanged);
        this.HandleRowLoadedCommand = new DelegateCommand<object>(this.handleRowLoaded);
        this.SearchRegisterCommand = new DelegateCommand<object>(this.searchRegister, searchRegisterCanExecute);
        this.VisualizeRegistersHierarchicallyCommand = new Prism.Commands.DelegateCommand(this.visualizeRegistersHierarchically, visualizeRegistersHierarchicallyCanExecute);
        this.VisualizeRegistersPlanarCommand = new Prism.Commands.DelegateCommand(this.visualizeRegistersPlanar, visualizeRegistersPlanarCanExecute);
        this.InitializeRegisterCurrentValueReadingCommand = new DelegateCommand<object>(this.initializeRegisterValueReading, this.initializeRegisterValueReadingCanExecute);
        // Register search button icon.
        string pathToImage = string.Copy(GlobalStaticMembers.PathToSearchIcon);
                this.ButtonImageSource = BitmapFrame.Create(new Uri(pathToImage, UriKind.Absolute));
    }
    . . . . . . . . . . . . .
    }

    The solution's structure you can see in 'Solution_structure_25_July_2016.PNG' file attached.

    Is there still any way to make the buttons fire the commands? I'm in need of solving this problem very.

  5. Martin Vatev
    Admin
    Martin Vatev avatar
    87 posts

    Posted 26 Jul Link to this post

    Hello Yaroslav,

    If I understand correctly, the problem in your case is that the button's Command property is searching for DelegateCommand in the wrong DataContext class. To fix the issue you should try to set it explicitly as a RelativeSource. If I am not wrong in the output window must contain binding errors when the application is running. 

    I hope this helps. If further assistance is needed, please feel free to get back to us.

    Regards,
    Martin Vatev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  6. Yaroslav
    Yaroslav avatar
    122 posts
    Member since:
    Jan 2016

    Posted 27 Jul in reply to Martin Vatev Link to this post

    Hello, Martin. You wrote: "...the button's Command property is searching for DelegateCommand in the wrong DataContext class." Why DataContext is wrong here

    You also wrote: "...To fix the issue you should try to set it explicitly as a RelativeSource...". What I should set explicity as a RelativeSourse? Button's Command property value in XAML markup?

  7. Yaroslav
    Yaroslav avatar
    122 posts
    Member since:
    Jan 2016

    Posted 28 Jul in reply to Yaroslav Link to this post

    Hello, Martin. Below is XAML markup of GridViewDataColumn which is button-column.

    <telerik:GridViewDataColumn>
        <telerik:GridViewDataColumn.CellTemplate>
            <DataTemplate>
                <telerik:RadButton Margin="5" Content="Read Register Value" Visibility="{Binding IsSelected,
                                        RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource booleanToVisibilityConverter}}"
                                                       Command="{Binding InitializeRegisterCurrentValueReadingCommand}"/>
            </DataTemplate>
        </telerik:GridViewDataColumn.CellTemplate>
    </telerik:GridViewDataColumn>

    Please show me - where I should set explicity 'RelativeSource' in XAML markup of this column? Thank you very much in advance.

  8. Answer
    Martin Vatev
    Admin
    Martin Vatev avatar
    87 posts

    Posted 29 Jul Link to this post

    Hello Yaroslav,

    To achieve the desired behavior you should find the visual element whose DataContext is DeviceParametersViewMode and access its InitializeRegisterCurrentValueReadingCommand property. To see what I have in mind please take a look at the code snippet below:

    <UserControl.Resources>
     
            <telerik:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
     
        <local:ViewModel x:Key="myViewModel"/>
     
    </UserControl.Resources>
     
    ...
     
    ...
     
    <telerik:GridViewDataColumn IsVisible="{Binding IsReadColumnButtonVisible}">
     
               <telerik:GridViewDataColumn.CellTemplate>
     
                   <DataTemplate>
     
                      <telerik:RadButton Margin="5" Content="Read Register Current Value" Visibility="{Binding IsSelected,
     
                                        RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}, Converter={StaticResource booleanToVisibilityConverter}}"
     
                                                       Command="{Binding DataContext.InitializeRegisterCurrentValueReadingCommand, RelativeSource={RelativeSource AncestorType={x:Type telerik:RadTreeListView}}"/>
     
                   </DataTemplate>
     
               </telerik:GridViewDataColumn.CellTemplate>
     
          </telerik:GridViewDataColumn>

    I hope that this helps.

    Regards,
    Martin Vatev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  9. Yaroslav
    Yaroslav avatar
    122 posts
    Member since:
    Jan 2016

    Posted 01 Aug in reply to Martin Vatev Link to this post

    Thank you very much, Martin, your help is great. It works. The problem solved.
Back to Top
UI for WPF is Visual Studio 2017 Ready