WPF PRISM MVVM从网格控件中获取所选项

时间:2016-02-17 08:20:58

标签: c# wpf mvvm devexpress prism

我有一个DevExpress网格控件。我想根据网格控件中的选定行启用/禁用按钮,即,如果在网格控件中选择了任何行,则应启用此按钮。以下是我的GridControl代码:

<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>

以下是我的ViewModel代码:

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;
    }
}

以下是按钮的xaml代码:

<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>

如何根据网格中是否选择了任何行来启用/禁用ShowStatus按钮?

2 个答案:

答案 0 :(得分:0)

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

CanShowStatusChange方法相同创建属性并将其绑定到要启用/禁用的按钮

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

选定的平面图不能是可观察的集合。名称表示它的a它表示单个对象。所以

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.
  }
}

确保在UI中绑定SelectedFloorplan属性和CanShowStatusChange属性,以便更新它们。

答案 1 :(得分:0)

1)IsEnabled将从CanShowStatusChange获得bool值,因此您不需要样式。

2)你在VM中选择了网格,所以为什么要通过参数传递它?

<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)你设置了SelectedFloorplan,然后你只需更改集合中的项目!这意味着我们应该在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)和

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;
    }
}