0
votes

I have a DevExpress Grid Control. I want to enable/disable a button based on the selected rows in the grid control, i.e., if any rows are selected in the grid control then this button should be enabled. Following is my GridControl code:

<dxg:GridControl x:Name="gridFloorplans" Grid.Column="1" Grid.Row="1" AutoGenerateColumns="None" 
            ItemsSource="{Binding FloorplanList.Result.View}"
            SelectedItems="{Binding SelectedFloorplan,Mode=TwoWay}"
            dx:ThemeManager.Theme="Default" SelectionMode="Row">
        <dxg:GridControl.View>
            <dxg:TableView AllowGrouping="False" ShowGroupPanel="False" AllowEditing="False"  ShowDataNavigator="True" DataNavigatorButtons="Navigation" />
        </dxg:GridControl.View>
        <dxg:GridControl.Columns>
            <dxg:GridColumn FieldName="Name" Header="Floorplan Name" Fixed="Left" />
            <dxg:GridColumn FieldName="Season"  Fixed="Left" />
            <dxg:GridColumn FieldName="Version"  Fixed="Left" />                
        </dxg:GridControl.Columns>            
</dxg:GridControl>

Following is my ViewModel code:

private ObservableCollection<FloorplanData> _selectedFloorplan;

public FloorplanSearchViewModel(IErrorHandlerService inErrorHandler, INavigationService inNavigationService, 
            ISpaDataAdapter inDataAdapter, IAuthorizationService inAuthService)
{            
    // Set the commands
    this.ShowStoreSetCommand = new DelegateCommand<IList<object>>(this.ShowStoreSet, this.CanShowStoreSet);
    this.SearchFloorplansCommand = new DelegateCommand(this.SearchFloorplans);
    this.ShowStatusChangeCommand = new DelegateCommand<IList<object>>(this.ShowStatusChange, this.CanShowStatusChange);

    // Set up the default values for the search
    this.StatusList = new List<object>();
    this.StatusList.Add(Enum.GetName(typeof(FloorplanData.FloorplanStatus), FloorplanData.FloorplanStatus.Pending));
    this.StatusList.Add(Enum.GetName(typeof(FloorplanData.FloorplanStatus), FloorplanData.FloorplanStatus.Review));

    //Initiate the SelectedFloorplan property
    //SelectedFloorplan = new ObservableCollection<FloorplanData>();
}



public ObservableCollection<FloorplanData> SelectedFloorplan
{
    get
    {
        return _selectedFloorplan;
    }
    set
    {
        _selectedFloorplan = value;
        this.ShowStatusChangeCommand.RaiseCanExecuteChanged();
    }
}

public NotifyTaskCompletion<CollectionViewSource> FloorplanList
{
    get;
    private set;
}

private void ShowStatusChange(IList<object> inFloorplans)
{
    try
    {
        // Create the navigation output
        NavigationParameters args = new NavigationParameters();
        args.Add(FloorplanStatusChangeViewModel.PARAM_FLOORPLAN_ID_LIST, GetFloorplanIdList(inFloorplans));
        _navigationService.NavigateTo<Views.FloorplanStatusChangeView>(args);
    }
    catch (Exception ex)
    {
        _errorHandler.HandleError(ex);
    }
}

private bool CanShowStatusChange(IList<object> inFloorplans)
{
    // Check security to see if the current user is allowed to enter the status change screen
    if (_authService.GetAccessLevel(1470) > AuthorizationLevel.None)
    {
        if (SelectedFloorplan!=null)
            return true;
        else
            return false;
    }
    else
    {
        return false;
    }
}

Following is the xaml code for the button:

<Button Margin="4,2" Content="Status Change"  Command="{Binding ShowStatusChangeCommand}" 
                    CommandParameter="{Binding SelectedItems, ElementName=gridFloorplans}">
                <Button.Style>
                    <Style TargetType="Button">
                        <Setter Property="ToolTip" Value="Open the Floorplan Status Change view for the selected floorplans" />
                        <Style.Triggers>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="ToolTip" Value="You do not have access to open the Floorplan Status Change view" />
                            </Trigger>
                            <DataTrigger 
                                Binding ="{Binding ElementName=gridFloorplans, Path=SelectedFloorplan}" 
                                Value="-1">
                                <Setter Property="Button.IsEnabled" Value="false"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Button.Style>
            </Button>

How can I enable/disable ShowStatus button based on whether any row is selected in the grid or not?

2
What is the problem now? Is your button binded to command? - galakt
Please look at my Button XAML code. It is not working. - Sormita Chakraborty
Put break point in ShowStatusChange method, press button. Do you hit break point? Does binding work correctly? Then we will continue - galakt
I am trying to get the execution inside CanStatusShow method but the execution reaches there only at the beginning but not during when I change row selection in grid. - Sormita Chakraborty

2 Answers

0
votes
//You are not using `inFloorplans` parameter within your method body
//Need not pass this parameter
private bool CanShowStatusChange(IList<object> inFloorplans)

Same as CanShowStatusChange method create a property and bind it to the Button which you want to enable/disable

public bool CanShowStatusChange
{
  get
  {  
    if (_authService.GetAccessLevel(1470) > AuthorizationLevel.None)
    {
        if (SelectedFloorplan!=null)
            return true;
        else
            return false;
    }
    else
    {
        return false;
    }
  }
}

Selected floor plan cant be an observable collection. The name detotes its a It denotes a single object. So

private FloorplanData _selectedFloorplan;
public FloorplanData SelectedFloorplan
{
  get
  {
   return _selectedFloorplan;
  }
  set
  {
    _selectedFloorplan = value;
    NotifyPropertyChanged("SelectedFloorplan");
     //or its equivalent method to notify the change
    NotifyPropertyChanged("CanShowStatusChange");
     //or its equivalent method to notify the change of CanShowStatusChange.
  }
}

Make sure you bind SelectedFloorplan property and CanShowStatusChange property in your UI so that they are updated.

0
votes

1) IsEnabled will get bool value from CanShowStatusChange, so you dont need style.

2) You have grid`s selected items in VM, so why pass it via parameter?

<Button Margin="4,2" Content="Status Change" Command="{Binding ShowStatusChangeCommand}">
    <Button.Style>
        <Style TargetType="Button">
            <Setter Property="ToolTip" Value="Open the Floorplan Status Change view for the selected floorplans" />
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="ToolTip" Value="You do not have access to open the Floorplan Status Change view" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

3) You set SelectedFloorplan ones, then you just change items in collection! It means than we should subscribe on CollectionChanged

public FloorplanSearchViewModel(IErrorHandlerService inErrorHandler, INavigationService inNavigationService, 
            ISpaDataAdapter inDataAdapter, IAuthorizationService inAuthService)
{            
    // Set the commands
    this.ShowStoreSetCommand = new DelegateCommand<IList<object>>(this.ShowStoreSet, this.CanShowStoreSet);
    this.SearchFloorplansCommand = new DelegateCommand(this.SearchFloorplans);
    this.ShowStatusChangeCommand = new DelegateCommand<IList<object>>(this.ShowStatusChange, this.CanShowStatusChange);

    // Set up the default values for the search
    this.StatusList = new List<object>();
    this.StatusList.Add(Enum.GetName(typeof(FloorplanData.FloorplanStatus), FloorplanData.FloorplanStatus.Pending));
    this.StatusList.Add(Enum.GetName(typeof(FloorplanData.FloorplanStatus), FloorplanData.FloorplanStatus.Review));

    //Initiate the SelectedFloorplan property
    SelectedFloorplan = new ObservableCollection<FloorplanData>();
    SelectedFloorplan.CollectionChanged += SelectedFloorplanOnCollectionChanged;
}


private void SelectedFloorplanOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
    this.ShowStatusChangeCommand.RaiseCanExecuteChanged();
}


public ObservableCollection<FloorplanData> SelectedFloorplan
{
    get
    {
        return _selectedFloorplan;
    }
    set
    {
        _selectedFloorplan = value;
        this.ShowStatusChangeCommand.RaiseCanExecuteChanged();
    }
}

4) And

private bool CanShowStatusChange()
{
    // Check security to see if the current user is allowed to enter the status change screen
    if (_authService.GetAccessLevel(1470) > AuthorizationLevel.None)
    {
        if (SelectedFloorplan!=null && SelectedFloorplan.Any())
            return true;
        else
            return false;
    }
    else
    {
        return false;
    }
}