2016-02-19 54 views
6

我在我的WPF應用程序中使用telerik RadGridView。其中一列具有以下功能:在事件發生之前禁用網格WPF

當用戶更改列的值時,會將command作爲事件觸發並顯示彈出窗口。使用彈出式結果(是或否),我正在更新collection

現在我在這裏面臨一個問題。

問題:

用戶正在改變column的價值在row之一,並出現警告之前,他是在同一個column另一個row改變。所以應用程序以不同的方式工作,功能崩潰。

工作的嘗試:

我試圖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); } } 

視圖模型:

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

我建議你在你的ViewModel中創建屬性IsGridEnabled,並在命令集IsGridEnabled = false的開始,在命令集的最後設置IsGridEnabled = false。當然,將你的grid.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. 增加了一個繁忙指示符(telerik的RadBusyIndi​​cator)。
  2. 該命令是在行的父級(RadGridView)ViewModel內定義的。
  3. 使用相對綁定來指向RadGridView的ViewModel中的命令。
  4. 由於UpdateValueEvent =「LostFocus」,每次用戶更改RadMaskedNumericInput的值並將焦點移動到其他位置(選項卡被按下或鼠標關閉到某個其他控件)時,引發「ValueChanged」事件,觸發器將會啓動命令,這個命令將會顯示BusyIndi​​cator,BusyIndi​​cator會鎖定網格視圖(RadGridView)。

如何,它看起來像: here is the picture

讓我知道,如果你需要的代碼更多的解釋。

問候。

+0

但是,在出現警報之前,我仍然很少能夠編輯下一行值。 – iamCR

+0

@SanthoshKumar你應該使用UpdateValueEvent =「LostFocus」。你使用這個屬性? – Ilan

+0

添加事件時,僅當用戶嘗試更改第二個值時纔會引發警報。如果用戶只更改一個值,則不會引發警報。你能幫我嗎?我需要當用戶更改警報應該拋出的值時。 – iamCR

相關問題