for c# wpf telerik radgridview

c# - radgridview telerik winforms



Desactivar grid antes del evento WPF (1)

Estoy usando telerik RadGridView en mi aplicación WPF . Una de las columnas tiene la siguiente funcionalidad,

Cuando el usuario cambia el valor de la columna, se activa un command como un evento y se muestra un pop. Usando el resultado emergente (Sí o No) estoy actualizando la collection .

Ahora estoy enfrentando un problema aquí.

Problema:

El usuario está cambiando el valor de esa column en una de las row y antes de que aparezca la alerta, está cambiando en otra row de la misma column . Entonces la aplicación funciona de una manera diferente y la funcionalidad colapsa.

Trabajo probado:

Traté de disable la grilla una vez que el evento se dispara y habilito después de que la función se haya completado. Pero aún así el usuario es muy rápido, incluso antes de que el evento triggers , está cambiando el valor.

XAML:

<telerik:GridViewDataColumn Name="grdItemBuildColumn" DataMemberBinding="{Binding Build, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnlyBinding="{Binding IsEnable, Mode=OneWay, UpdateSourceTrigger= PropertyChanged}"> <telerik:GridViewDataColumn.CellEditTemplate> <DataTemplate> <telerik:RadMaskedNumericInput Value="{Binding Build, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Mask="#1.0" Placeholder=" " TextMode="PlainText" AllowInvalidValues="False" IsClearButtonVisible="False" AutoFillNumberGroupSeparators="False"ext:MaskedInputExtensions.Minimum="0" SelectionOnFocus="SelectAll" AcceptsReturn="False"> <i:Interaction.Triggers> <i:EventTrigger EventName="ValueChanged"> <i:InvokeCommandAction Command="{Binding BuidValueChangedCommand, Source={StaticResource MarketSeriesViewModel}}" /> </i:EventTrigger> </i:Interaction.Triggers> </telerik:RadMaskedNumericInput> </DataTemplate> </telerik:GridViewDataColumn.CellEditTemplate> </telerik:GridViewDataColumn>

Mando:

public ICommand BuidValueChangedCommand { get { return new RelayCommand(BuildValueChanged); } }

ViewModel:

private void BuildValueChanged() { // Ask confirmation for delete. if (ShowMessages.MessageBox("This will be removed from the collection", "Application")) { DeleteItem(SelectedItem.Id) } else { Item bo = RestoreBuild(SelectedItem); SelectedItem = bo; } }

Solo necesito algo como restringir al usuario para que no cambie el segundo valor hasta que se triggers el evento y seleccione algo (Sí / No) del menú emergente.

¿Puede alguien ayudarme con esto?


por favor intente el siguiente:

Xaml

<Grid> <telerik:RadBusyIndicator IsBusy="{Binding ImBusy, UpdateSourceTrigger=PropertyChanged}"> <telerik:RadGridView Margin="2" ItemsSource="{Binding ChannelRuleMappings}" SelectionUnit="FullRow" SelectionMode="Extended" AutoGenerateColumns="False" IsFilteringAllowed="False"> <telerik:RadGridView.Columns> <telerik:GridViewDataColumn Name="grdItemBuildColumn" DataMemberBinding="{Binding Build, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnlyBinding="{Binding IsEnable, Mode=OneWay, UpdateSourceTrigger= PropertyChanged}"> <telerik:GridViewDataColumn.CellEditTemplate> <DataTemplate> <telerik:RadMaskedNumericInput Value="{Binding Build, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Mask="#1.0" Placeholder="*" TextMode="PlainText" UpdateValueEvent="LostFocus" AllowInvalidValues="False" IsClearButtonVisible="False" AutoFillNumberGroupSeparators="False" maskedInput:MaskedInputExtensions.Minimum="0" SelectionOnFocus="SelectAll" AcceptsReturn="False"> <i:Interaction.Triggers> <i:EventTrigger EventName="ValueChanged"> <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadGridView}}, Path=DataContext.BuidValueChangedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </telerik:RadMaskedNumericInput> </DataTemplate> </telerik:GridViewDataColumn.CellEditTemplate> </telerik:GridViewDataColumn> </telerik:RadGridView.Columns> </telerik:RadGridView> </telerik:RadBusyIndicator> </Grid>

VM y modelos

//GridView VM - screen is a simple implementation of the INPC public class StackOptimizerChannelRulesViewModel : Screen { //provides values for grid view items source collection private readonly IStackOptimizerStep _step; //IUserInteractionService is a simple implementation of the massage box service private readonly IUserInteractionService _interactionService; private bool _imBusy; public StackOptimizerChannelRulesViewModel(IStackOptimizerStep step, IUserInteractionService interactionService) { _step = step; _interactionService = interactionService; DisplayName = "Channels Rules"; ChannelRuleMappings = new ObservableCollection<ChannelRuleMappingModelBase>(); } protected override void OnInitialize() { base.OnInitialize(); Init(); } public ObservableCollection<ChannelRuleMappingModelBase> ChannelRuleMappings { get; set; } //allows to show the vbusy indicator public bool ImBusy { get { return _imBusy; } set { _imBusy = value; NotifyOfPropertyChange(()=>ImBusy); } } private ICommand _cmd; public ICommand BuidValueChangedCommand { get { return _cmd ?? (_cmd = new ActionCommand(BuildValueChanged)); } } private void BuildValueChanged() { ImBusy = true; // Ask confirmation for delete. if (_interactionService.AskYesNo("This will be removed from the collection")) { //Add yor logic on yes ImBusy = false; } else { //Add yor logic on no ImBusy = false; } } private void Init() { var channelRuleMappings = _step.GetRulesForChannels(); if (channelRuleMappings != null) channelRuleMappings.ForEach(parameter => ChannelRuleMappings.Add(new ChannelRuleMappingModel(parameter, _interactionService))); } } //Row VM base public class ChannelRuleMappingModelBase : PropertyChangedBase { private string _name; private readonly IUserInteractionService _interactionService; private StackOptimizerSelectionRules _stackOptimizerSelectedRule; private object _build; public ChannelRuleMappingModelBase(string channelName, IUserInteractionService interactionService) { _name = channelName; _interactionService = interactionService; } public virtual string Name { get { return _name; } } public virtual StackOptimizerSelectionRules StackOptimizerSelectedRule { get { return _stackOptimizerSelectedRule; } set { _stackOptimizerSelectedRule = value; NotifyOfPropertyChange(() => StackOptimizerSelectedRule); } } public object Build { get { return _build; } set { _build = value; NotifyOfPropertyChange(() => Build); } } } //Row VM public class ChannelRuleMappingModel : ChannelRuleMappingModelBase { private StackOptimizerSelectionRules _stackOptimizerSelectedRule; private ISpectrumRuleParameter _ruleMapping; public ChannelRuleMappingModel(ISpectrumRuleParameter ruleMapping, IUserInteractionService interactionService): base(ruleMapping.PolarizationKey.Name, interactionService) { _ruleMapping = ruleMapping; _stackOptimizerSelectedRule = _ruleMapping.Rule; } public override StackOptimizerSelectionRules StackOptimizerSelectedRule { get { return _stackOptimizerSelectedRule; } set { _stackOptimizerSelectedRule = value; NotifyOfPropertyChange(() => StackOptimizerSelectedRule); UpdateOriginalRuleMapping(StackOptimizerSelectedRule); } } private void UpdateOriginalRuleMapping(StackOptimizerSelectionRules stackOptimizerSelectedRule) { if(_ruleMapping == null) return; _ruleMapping.Rule = stackOptimizerSelectedRule; } }

Pequeña explicación:

  1. Se agregó un indicador de ocupado (RadBusyIndicator de telerik).
  2. El comando se definió en el ViewModel principal de la fila (RadGridView).
  3. Se utiliza una vinculación relativa para apuntar al comando dentro del ViewModel de RadGridView.
  4. Cada vez que el usuario cambia el valor de RadMaskedNumericInput y mueve el foco al otro lugar (se presionó la pestaña o el mouse bajó a algún otro control) debido a UpdateValueEvent = "LostFocus" el evento "ValueChanged" se activa, el disparador iniciará el comando , este comando hará que se muestre el BusyIndicator, el BusyIndicator bloqueará la vista de la cuadrícula (RadGridView).

Como se ve:

Avíseme si necesita más explicación para el código.

Saludos.