2016-02-19 3 views
6

Я использую telerik RadGridView в своем приложении WPF. Один из столбцов имеет следующую функциональность:Отключить сетку перед пожаром события WPF

Когда пользователь меняет значение столбца, а command запускается как событие, и отображается поп. Используя всплывающий результат (Да или Нет), я обновляю collection.

Теперь я столкнулся с проблемой здесь.

Выпуск:

Пользователь изменяет значение этого column в одном из row и до появления предупреждения он меняется в другом row того же column. Таким образом, приложение работает по-другому, и функциональность сворачивается.

Работа Пробовала:

Я попытался disable сетки раз костров событий и включить после выполнения функции будет завершена. Но все же пользователь очень быстро еще до события triggers, он меняет значение.

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> 

Команда:

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

мне просто нужно что-то вроде ре чтобы пользователь не менял второе значение до события triggers, и он выбирает что-то (Да/Нет) из всплывающего окна.

Может кто-нибудь помочь мне с этим?

+0

Я предлагаю вам создать свойство IsGridEnabled в вашей ViewModel и в начале набора команд IsGridEnabled = false, в конце набора команд IsGridEnabled = false. И, конечно, свяжите свою сетку.IsEnabled к этому свойству –

+0

@ ВасилийШапенко: Пробовал это, но пользователь меняет значение даже до того, как будет запущено событие (команда). – iamCR

+0

Использует ли ваш viewModel метод INotifyPropertyChanged? – ProgrammingDude

ответ

3

пожалуйста, попробуйте следующее:

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 и модели

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

Малый объяснение:

  1. Добавлен индикатор занятости (идентификатор RadBusyIndicator от telerik).
  2. Команда была определена внутри родительского элемента (RadGridView) ViewModel.
  3. Относительное связывание используется для указания команды внутри ViewModel RadGridView.
  4. Каждый раз, когда пользователь меняет значение RadMaskedNumericInput и перемещает фокус на другое место (вкладка была нажата, или мышь была недоступна для какого-либо другого элемента управления) из-за UpdateValueEvent = "LostFocus" событие ValueChanged было поднято, триггер будет запустите команду, эта команда вызовет отображение BusyIndicator, BusyIndicator заблокирует представление сетки (RadGridView).

Как это выглядит: here is the picture

Позвольте мне знать, если вам нужно больше объяснений к коду.

С уважением.

+0

Но все же в редкое время я могу редактировать значение следующей строки до появления предупреждения. – iamCR

+0

@SanthoshKumar вы должны использовать UpdateValueEvent = "LostFocus". Вы использовали это свойство? – Ilan

+0

При добавлении события предупреждение вызывается только тогда, когда пользователь пытается изменить второе значение. Если пользователь изменяет только одно значение, предупреждение не выбрасывается. ты можешь меня достать? Мне нужно, когда пользователь изменяет значение, которое должно быть выбрано. – iamCR