This is a migrated thread and some comments may be shown as answers.

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

7 Answers 138 Views
TreeListView
This is a migrated thread and some comments may be shown as answers.
Dmitry
Top achievements
Rank 1
Dmitry asked on 20 Jul 2016, 06:13 AM

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.

7 Answers, 1 is accepted

Sort by
0
Martin
Telerik team
answered on 25 Jul 2016, 05:30 AM
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.
0
Dmitry
Top achievements
Rank 1
answered on 25 Jul 2016, 10:18 AM

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.

0
Martin
Telerik team
answered on 26 Jul 2016, 12:22 PM
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.
0
Dmitry
Top achievements
Rank 1
answered on 27 Jul 2016, 01:52 PM

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?

0
Dmitry
Top achievements
Rank 1
answered on 28 Jul 2016, 09:43 AM

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.

0
Accepted
Martin
Telerik team
answered on 29 Jul 2016, 11:52 AM
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.
0
Dmitry
Top achievements
Rank 1
answered on 01 Aug 2016, 10:50 AM
Thank you very much, Martin, your help is great. It works. The problem solved.
Tags
TreeListView
Asked by
Dmitry
Top achievements
Rank 1
Answers by
Martin
Telerik team
Dmitry
Top achievements
Rank 1
Share this question
or