WPF 无法从用户控件中移除红色边框

huangapple go评论52阅读模式
英文:

WPF Can't Remove Red Border from UserControl

问题

以下是您要翻译的内容:

I've built a simple login page and when invalid input is detected, a red border is drawn around the usercontrol.

WPF 无法从用户控件中移除红色边框

Here is my layout code:

<UserControl x:Class="WPFTest.UI.Views.EmptyLayout"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFTest.UI.Views"
             xmlns:vm="clr-namespace:WPFTest.UI.ViewModels"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800"
             d:DataContext="{d:DesignInstance Type=vm:EmptyLayoutViewModel}"
             Background="White"
             >
    <Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" FontSize="20" FontWeight="Bold">Test Sales Estimator</TextBlock>
    <ContentControl Content="{Binding Layout}" Grid.Row="1">
        <ContentControl.Resources>
                <DataTemplate DataType="{x:Type vm:LoginViewModel}">
                    <local:LoginView/>
                </DataTemplate>
            </ContentControl.Resources>
    </ContentControl>
    </Grid>
</UserControl>

And here is the login view:

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFTest.UI.Views" xmlns:viewmodels="clr-namespace:WPFTest.UI.ViewModels"
             xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" x:Class="WPFTest.UI.Views.LoginView"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800"
             Background="White"
             d:DataContext="{d:DesignInstance Type={x:Type viewmodels:LoginViewModel}}"
             Margin="20 0 0 0"
             Padding="10"
             >   
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Row="2" Margin="0 50 0 0">
            <TextBlock Text="Welcome" FontSize="17" Grid.Row="1" Margin="0 0 0 20" Height="50"/>
            <StackPanel>
                <TextBlock Text="Username" />
                <TextBox Text="{Binding Username}"/>
            </StackPanel>

            <StackPanel Grid.Row="2" Margin="0 10 0 0">
                <TextBlock Text="Password"  />
                <PasswordBox x:Name="Password" PasswordChanged="PasswordBox_PasswordChanged" >
                </PasswordBox>
            </StackPanel>
            <Button
            Grid.Row="2"
            Margin="0 20 0 0"
            Padding="5 2"
            HorizontalAlignment="Left"
            Command="{Binding HandleLoginCommand}"
            IsEnabled="{Binding CanLogin}"
            Content="Login">

            </Button>
        </StackPanel>
    </Grid>
</UserControl>

I have tried to override the border with the following template:

    <Style TargetType="views:LoginView">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="BorderBrush" Value="Blue"/>
                <Setter Property="BorderThickness" Value="1"/>
            </Trigger>
        </Style.Triggers>
    </Style>

But the border remains red. I've also tried changing the target on the template to things like UserControl, and ContentControl. I've also tried setting the Validation.ErrorTemplate attribute to {x:Null} on both the UserControl and on the element inside the layout usercontrol.

For the LoginViewModel, I am using the CommunityToolkit.Mvvm's ObservableValidator as my base class, so it handles the validation logic and here is my Username property.

 private string _username;
        [Required]
        [MinLength(4)]
        public string Username
        {
            get { return _username; }
            set { 
                SetProperty(ref _username, value, true);
                OnPropertyChanged(nameof(HandleLoginCommand));
            }
        }
英文:

I've built a simple login page and when invalid input is detected, a red border is drawn around the usercontrol.
WPF 无法从用户控件中移除红色边框

Here is my layout code:

&lt;UserControl x:Class=&quot;WPFTest.UI.Views.EmptyLayout&quot;
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot; 
             xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot; 
             xmlns:local=&quot;clr-namespace:WPFTest.UI.Views&quot;
             xmlns:vm=&quot;clr-namespace:WPFTest.UI.ViewModels&quot;
             mc:Ignorable=&quot;d&quot; 
             d:DesignHeight=&quot;450&quot; d:DesignWidth=&quot;800&quot;
             d:DataContext=&quot;{d:DesignInstance Type=vm:EmptyLayoutViewModel}&quot;
             Background=&quot;White&quot;
             &gt;
    &lt;Grid Margin=&quot;20&quot;&gt;
        &lt;Grid.RowDefinitions&gt;
            &lt;RowDefinition Height=&quot;50&quot;&gt;&lt;/RowDefinition&gt;
            &lt;RowDefinition&gt;&lt;/RowDefinition&gt;
        &lt;/Grid.RowDefinitions&gt;
        &lt;TextBlock Grid.Row=&quot;0&quot; FontSize=&quot;20&quot; FontWeight=&quot;Bold&quot;&gt;Test Sales Estimator&lt;/TextBlock&gt;
    &lt;ContentControl Content=&quot;{Binding Layout}&quot; Grid.Row=&quot;1&quot;&gt;
        &lt;ContentControl.Resources&gt;
                &lt;DataTemplate DataType=&quot;{x:Type vm:LoginViewModel}&quot;&gt;
                    &lt;local:LoginView/&gt;
                &lt;/DataTemplate&gt;
            &lt;/ContentControl.Resources&gt;
    &lt;/ContentControl&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;

And here is the login view:

&lt;UserControl
             xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
             xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
             xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot; 
             xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot; 
             xmlns:local=&quot;clr-namespace:WPFTest.UI.Views&quot; xmlns:viewmodels=&quot;clr-namespace:WPFTest.UI.ViewModels&quot;
             xmlns:mah=&quot;http://metro.mahapps.com/winfx/xaml/controls&quot; x:Class=&quot;WPFTest.UI.Views.LoginView&quot;
             mc:Ignorable=&quot;d&quot;
             d:DesignHeight=&quot;450&quot; d:DesignWidth=&quot;800&quot;
             Background=&quot;White&quot;
             d:DataContext=&quot;{d:DesignInstance Type={x:Type viewmodels:LoginViewModel}}&quot;
             Margin=&quot;20 0 0 0&quot;
             Padding=&quot;10&quot;
             &gt;   
    &lt;Grid&gt;
        &lt;Grid.ColumnDefinitions&gt;
            &lt;ColumnDefinition Width=&quot;150&quot; /&gt;
        &lt;/Grid.ColumnDefinitions&gt;

        &lt;StackPanel Grid.Row=&quot;2&quot; Margin=&quot;0 50 0 0&quot;&gt;
            &lt;TextBlock Text=&quot;Welcome&quot; FontSize=&quot;17&quot; Grid.Row=&quot;1&quot; Margin=&quot;0 0 0 20&quot; Height=&quot;50&quot;/&gt;
            &lt;StackPanel&gt;
                &lt;TextBlock Text=&quot;Username&quot; /&gt;
                &lt;TextBox Text=&quot;{Binding Username}&quot;/&gt;
            &lt;/StackPanel&gt;

            &lt;StackPanel Grid.Row=&quot;2&quot; Margin=&quot;0 10 0 0&quot;&gt;
                &lt;TextBlock Text=&quot;Password&quot;  /&gt;
                &lt;PasswordBox x:Name=&quot;Password&quot; PasswordChanged=&quot;PasswordBox_PasswordChanged&quot; &gt;
                &lt;/PasswordBox&gt;
            &lt;/StackPanel&gt;
            &lt;Button
            Grid.Row=&quot;2&quot;
            Margin=&quot;0 20 0 0&quot;
            Padding=&quot;5 2&quot;
            HorizontalAlignment=&quot;Left&quot;
            Command=&quot;{Binding HandleLoginCommand}&quot;
            IsEnabled=&quot;{Binding CanLogin}&quot;
            Content=&quot;Login&quot;&gt;

            &lt;/Button&gt;
        &lt;/StackPanel&gt;
    &lt;/Grid&gt;
&lt;/UserControl&gt;

I have tried to override the border with the following template:

    &lt;Style TargetType=&quot;views:LoginView&quot;&gt;
        &lt;Style.Triggers&gt;
            &lt;Trigger Property=&quot;Validation.HasError&quot; Value=&quot;True&quot;&gt;
                &lt;Setter Property=&quot;BorderBrush&quot; Value=&quot;Blue&quot;/&gt;
                &lt;Setter Property=&quot;BorderThickness&quot; Value=&quot;1&quot;/&gt;
            &lt;/Trigger&gt;
        &lt;/Style.Triggers&gt;
    &lt;/Style&gt;

But the border remains red. I've also tried changing the target on the template to things like UserControl, and ContentControl. I've also tried setting the Validation.ErrorTemplate attribute to {x:Null} on both the UserControl and on the element inside the layout usercontrol.

For the LoginViewModel, I am using the CommunityToolkit.Mvvm's ObservableValidator as my base class, so it handles the validation logic and here is my Username property.

 private string _username;
        [Required]
        [MinLength(4)]
        public string Username
        {
            get { return _username; }
            set { 
                SetProperty(ref _username, value, true);
                OnPropertyChanged(nameof(HandleLoginCommand));
            }
        }

答案1

得分: 2

以下是翻译好的内容:

"Set Validation.ErrorTemplate="{x:Null}" on that." 可以翻译为 "在此上设置 Validation.ErrorTemplate="{x:Null}"。"

"You can just use a contentpresenter." 可以翻译为 "你可以只使用一个 ContentPresenter。"

"<DataTemplate DataType="{x:Type local:LoginViewModel}">" 可以翻译为 "<DataTemplate DataType="{x:Type local:LoginViewModel}">"

"I have a simplified layout to explore this, but the outer red border does not appear when I make that change." 可以翻译为 "我有一个简化的布局来探索这个问题,但当我进行更改时,外部的红色边框不会出现。"

英文:

The border is from your contentcontrol.

Set Validation.ErrorTemplate="{x:Null}" on that.

You can just use a contentpresenter.

    &lt;ContentPresenter Content=&quot;{Binding Layout}&quot;  Grid.Row=&quot;1&quot;
                      Validation.ErrorTemplate=&quot;{x:Null}&quot;&gt;
        &lt;ContentPresenter.Resources&gt;
            &lt;DataTemplate DataType=&quot;{x:Type local:LoginViewModel}&quot;&gt;
                &lt;local:LoginView/&gt;
            &lt;/DataTemplate&gt;
        &lt;/ContentPresenter.Resources&gt;
    &lt;/ContentPresenter&gt;

I have a simplified layout to explore this, but the outer red border does not appear when I make that change.

WPF 无法从用户控件中移除红色边框

答案2

得分: 0

验证装饰不使用控件的边框(Thickness/Brush)。它实际上是一个单独的 Visual,在单独的 AdornerLayer 中绘制。要修改其外观,您应该传递一个专用的 ErrorTemplate 模板,如下所示:(TextBox 的示例)

<Style TargetType="TextBox">
  <Setter Property="Validation.ErrorTemplate">
    <Setter.Value>
      <ControlTemplate>
        <Grid>
          <Border BorderBrush="Yellow" BorderThickness="3">
            <AdornedElementPlaceholder x:Name="AdornedElementPlaceholder" />
          </Border>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

要实际移除边框,尝试将 Validation.ErrorTemplate 设置为 {x:Null}

英文:

The validation decoration does not use the control's Border(Thcikness/Brush). It is instead a separate Visual that is drawn in a separate AdornerLayer. To modify its looks, you should pass a dedicated template for the ErrorTemplate like this: (example for TextBox)

&lt;Style TargetType=&quot;TextBox&quot;&gt;
  &lt;Setter Property=&quot;Validation.ErrorTemplate&quot;&gt;
    &lt;Setter.Value&gt;
      &lt;ControlTemplate&gt;
        &lt;Grid&gt;
          &lt;Border BorderBrush=&quot;Yellow&quot; BorderThickness=&quot;3&quot;&gt;
            &lt;AdornedElementPlaceholder x:Name=&quot;AdornedElementPlaceholder&quot; /&gt;
          &lt;/Border&gt;
        &lt;/Grid&gt;
      &lt;/ControlTemplate&gt;
    &lt;/Setter.Value&gt;
  &lt;/Setter&gt;
&lt;/Style&gt;

To actually remove the border, try setting Validation.ErrorTemplate to {x:Null}.

huangapple
  • 本文由 发表于 2023年2月14日 22:31:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75449298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定