簡體   English   中英

在固定位置顯示WPF驗證錯誤消息

[英]Show WPF validation error message in a fixed place

我運行了WPF驗證(將ValidationRules添加到綁定中)並且使用模板我可以創建漂亮的裝飾器。 那里有很多帖子。

但我找不到一種方法來在窗口一角的固定位置(例如TextBlock中顯示裝飾控件之外的錯誤消息,例如

我怎么能實現這個目標? 我可以將所有驗證錯誤消息綁定到我的DataContext (此處為ViewModel)嗎?


更新:感謝答案我得到了部分工作。 驗證消息現在顯示在另一個標簽中。 由於所有帶有驗證規則的文本框都是通過代碼動態創建的,因此以這種方式完成綁定:

Binding bindSite = new Binding();
bindSite.Source = this.validationErrorDisplayLabel;
BindingOperations.SetBinding(textBox, Validation.ValidationAdornerSiteProperty, bindSite);

但驗證消息僅轉發給執行此代碼的最后一個文本框的adornersite


我在這個小例子中重現了這個問題。

XAML:

<Grid>
    <TextBox 
        Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}"
        HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
        <TextBox.Text>
            <Binding>
                <Binding.Path>Box1</Binding.Path>
                <Binding.ValidationRules>
                    <local:RuleA />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBox 
        Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}"
        HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
        <TextBox.Text>
            <Binding>
                <Binding.Path>Box2</Binding.Path>
                <Binding.ValidationRules>
                    <local:RuleA />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
    <TextBlock 
        x:Name="ErrorDisplay"
        Background="AntiqueWhite"
        Foreground="Red"
        Text="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)[0].ErrorContent}"
        HorizontalAlignment="Left" Margin="230,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" RenderTransformOrigin="2.218,-4.577" Width="177" Height="51"/>
</Grid>

當值等於字符串"A"時,類RuleA會生成驗證錯誤。 第二個文本框中的錯誤顯示在TextBlock中,第一個錯誤不是(而是使用默認模板並獲得紅色邊框)。

它如何適用於兩者? 文本塊不需要總結所有錯誤,但顯示第一個錯誤。

您可以將BindingGroupValidation.ValidationAdornerSiteValidation.ValidationAdornerSiteFor屬性結合使用。

此博客文章向您展示了如何執行此操作的示例。


<StackPanel x:Name="FormRoot"
            Validation.ValidationAdornerSite="{Binding ElementName=ErrorDisplay}">
  <FrameworkElement.BindingGroup>
    <BindingGroup Name="FormBindingGroup" />
  </FrameworkElement.BindingGroup>

  <TextBox>
    <TextBox.Text>
      <Binding BindingGroupName="FormBindingGroup"
               UpdateSourceTrigger="LostFocus"
               Path="Box1">
        <Binding.ValidationRules>
          <l:RuleA />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>
  </TextBox>

<TextBox>
    <TextBox.Text>
      <Binding BindingGroupName="FormBindingGroup"
               UpdateSourceTrigger="LostFocus"
               Path="Box2">
        <Binding.ValidationRules>
          <l:RuleA />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>
  </TextBox>

  <ItemsControl x:Name="ErrorDisplay"
                Background="AntiqueWhite"
                Foreground="Red"
                ItemsSource="{Binding RelativeSource={RelativeSource Self},
                                      Path=(Validation.ValidationAdornerSiteFor).(Validation.Errors)}"
                DisplayMemberPath="ErrorContent" />
</StackPanel>

要在用戶鍵入時提交值,請將UpdateSourceTrigger值更改為PropertyChanged 請注意,此處不必嚴格使用ValidationAdornerSite ; 你可以簡單地指向ErrorDisplay直接結合的所有者BindingGroup

ItemsSource="{Binding ElementName=FormRoot, Path=(Validation.Errors)}"

感謝http://www.scottlogic.com/blog/2008/11/28/using-bindinggroups-for-greater-control-over-input-validation.html我能夠使用BindingGroup和沒有ValidationAdornerSite來解決這個問題。

<Window x:Class="BindingAndValidation.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingAndValidation"
        Title="Binding and Validation" Height="110" Width="425"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        >
    <Grid x:Name="RootElement">
        <Grid.Resources>
            <Style TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>
        <Grid.BindingGroup>
            <BindingGroup Name="LocalBindingGroup">
                <BindingGroup.ValidationRules>
                    <local:RuleGroup />
                </BindingGroup.ValidationRules>
            </BindingGroup>
        </Grid.BindingGroup>
        <TextBox 
            HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" LostFocus="TextBox_LostFocus">
            <TextBox.Text>
                <Binding>
                    <Binding.Path>Box1</Binding.Path>
                    <Binding.BindingGroupName>LocalBindingGroup</Binding.BindingGroupName>
                    <Binding.ValidationRules>
                        <local:RuleA />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <TextBox 
            HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
            <TextBox.Text>
                <Binding>
                    <Binding.Path>Box2</Binding.Path>
                    <Binding.BindingGroupName>LocalBindingGroup</Binding.BindingGroupName>
                    <Binding.ValidationRules>
                        <local:RuleA />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <ItemsControl ItemsSource="{Binding Path=(Validation.Errors), ElementName=RootElement}" MinWidth="100" MinHeight="16" Margin="230,10,0,0" Background="AntiqueWhite" Foreground="Red">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Label Foreground="Red" Content="{Binding Path=ErrorContent}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button Content="Button" HorizontalAlignment="Left" Margin="150,0,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" />
    </Grid>
</Window>

只有在調用CommitEdit時才會進行驗證。 如果你想立刻就像我希望的那樣你可以使用LostFocus

    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        this.RootElement.BindingGroup.CommitEdit();
    }

當然,對於更大的項目,附屬財產可能會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM