简体   繁体   English

当dataTemplate验证MVM VM WPF时CanExecute不禁用按钮

[英]CanExecute does not disable button when dataTemplate validation mvvm wpf

I have a dynamically generated window with some textboxes that have validation rule. 我有一个动态生成的窗口,其中包含一些具有验证规则的文本框。 The textbox validation is working, I can see the new style I have added, but I linked the IsValid function to CanExecute on save button and the button is always enabled, even if textbox validation is error. 文本框验证正在运行,我可以看到添加的新样式,但是我将IsValid函数链接到“保存时可以执行”按钮,即使文本框验证错误,该按钮也始终处于启用状态。
Can anyone give me a hint what I`m missing? 谁能给我一个提示,我想念什么?
Here is my window: 这是我的窗口:

<ScrollViewer Grid.Row="0" VerticalScrollBarVisibility="Auto">
            <ItemsControl ItemsSource = "{Binding Path = List}" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation = "Horizontal">
                            <Grid>    
                                <TextBox >
                                    <TextBox.Text>
                                        <Binding Path="Path" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" Mode="TwoWay" ValidatesOnNotifyDataErrors="True">
                                            <Binding.ValidationRules>
                                                <validationrules:FolderValidationRule/>
                                            </Binding.ValidationRules>
                                        </Binding>
                                    </TextBox.Text>
                                    <TextBox.Style>
                                        <Style TargetType="TextBox">
                                            <Style.Triggers>
                                                <Trigger Property="Validation.HasError" Value="True">
                                                    <Setter Property="Background" Value="Pink"/>
                                                    <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                                                </Trigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBox.Style>
                                </TextBox>
                            </Grid>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>      
        <Button Grid.Row="1" Content="Save" Command="{Binding ApplyChanges, Mode=TwoWay}" CommandParameter="{Binding ElementName=EditNewForm}" VerticalAlignment="Bottom" Width="114" Height="23" Margin="246,0,34,7"/>

the command: 命令:

 public RelayCommand<Window> ApplyChanges { get; private set; }
 ApplyChanges = new RelayCommand<Window>(ApplyChangesCommand, CanSaveExecute);

and the code: 和代码:

 private bool IsValid(DependencyObject obj)
    {
      if (obj != null)
      {
        return !Validation.GetHasError(obj) && LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>().All(IsValid);
      }
      return true;

    }
    private bool CanSaveExecute(Window sender)
    {
      bool valid = IsValid(sender as DependencyObject);
      return valid;
    }

I am assuming that your RelayCommand implementation has something like this: 我假设您的RelayCommand实现具有以下内容:

public event EventHandler CanExecuteChanged
{
  add { CommandManager.RequerySuggested += value; }
  remove { CommandManager.RequerySuggested -= value; }
}

This hands the control over to the UI to query the CanExecute condition when it feels like it is appropriate, and it would not be an easy task to tell you exactly when that is. 感觉合适时,这会将控件移交给UI来查询CanExecute条件,而要告诉您确切的时间并不容易。 For the most part it works quite well, but not always. 在大多数情况下,它工作得很好,但并非总是如此。 At times, you have to force a Requery if it is not working as expected. 有时,如果无法按预期运行,则必须强制执行Requery。 Simply call the static method below: 只需调用以下静态方法:

CommandManager.InvalidateRequerySuggested();

This will invalidate the command bindings and force the UI to query the CanExecute condition for all the UI elements that utilize it. 这将使命令绑定无效,并强制UI向使用该条件的所有UI元素查询CanExecute条件。 It's hard to say where you would call that as there is no code in the question, but I imagine your DataContext knows when the text changes in the TextBox in question. 由于问题中没有代码,因此很难说出该怎么称呼,但是我想您的DataContext知道何时在有问题的TextBox中更改文本。 Try calling it whenever the object bound to the TextBox changes. 每当绑定到TextBox的对象发生更改时,请尝试调用它。 Not the prettiest approach, but it always works. 不是最漂亮的方法,但它总是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM