【问题标题】:ControlTempate wpf Textbox not showing text and trigger propertiesControlTempate wpf 文本框不显示文本和触发器属性
【发布时间】:2015-09-10 13:47:04
【问题描述】:

我将继续学习 C# WPF 中的一个小项目。我目前的情况是我想在用户输入发生错误时更改TextBox 的边框,例如无法将他们的输入解析为十进制数。

经过一番阅读,我使用了一个控件模板,XAML 在下面,但是当我使用控件模板(textBox1)运行项目时,TextBox不显示任何文字,我看不出我做错了什么。有人可以帮忙吗?

我还在学习时使用IsMouseOver 属性触发更改,但在我的项目中我想触发一个错误属性,所以在我看来我需要添加到我的TextBox 控制属性@ 987654325@ 作为 bool 并且在我的代码后面,当我测试用户输入并且解析失败时,我会将 TextBox 属性 IsError 设置为 true,这将触发 ControlTemplate 更改。但是,这可以做到还是有更稳定的方法来做到这一点? 谢谢。

XAML of ControlTemplate

<Window x:Class="TestContentStyle.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="StyleTriggersSample" Height="100" Width="300">
<Window.Resources>
    <!--A ControlTemplate for textbox including error-->
    <ControlTemplate TargetType ="TextBox" x:Key="OnError">
        <TextBox   Name="TextBox"
                    FontSize="28" 
                    HorizontalAlignment="Center" 
                    VerticalAlignment="Center" 
                    BorderBrush="Silver"
                    BorderThickness="1"
                    Height="50"
                    Width="120"/>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver"
                            Value="True">
                        <Setter TargetName="TextBox"
                            Property="BorderThickness"
                            Value="5" />
                    </Trigger>
                </ControlTemplate.Triggers>
    </ControlTemplate>



</Window.Resources>

    <Grid>

    <TextBox Text="Tesing1" Margin="146,23,0,0" Name="textBox1" Template="{StaticResource OnError}" />
    <TextBox Text="Testing2" Height="23" HorizontalAlignment="Left" Margin="12,23,0,0" Name="Test1"  VerticalAlignment="Top" Width="120" />
</Grid>

【问题讨论】:

  • 您可以使用 WPF 附带的内置验证来完成此操作
  • 验证方法示例我看到所有使用的视图模型,坦率地说,对我来说是先进的
  • 您在 ControlTemplateControlTemplate 中使用了 TextBox,这没有任何意义。

标签: c# wpf xaml


【解决方案1】:

首先,模板定义了控件的呈现方式。他们定义了他们的整体外观。

你告诉TextBox 用另一个不同的TextBox 渲染自己。这意味着您在应用程序中看到的TextBox 实际上并不是您在Grid 中定义的带有“Testing1”文本的那个,而是您在ControlTemplate 中定义的那个有没有设置文本。

但除此之外,您不需要一个全新的ControlTemplate。你只需要一个Style:

<Window.Resources>
    <Style TargetType="TextBox" x:Key="OnError">
        <Setter Property="FontSize" Value="28" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="BorderBrush" Value="Silver" />
        <Setter Property="Height" Value="50" />
        <Setter Property="Width" Value="120" />
        <Style.Triggers>
            <Trigger Property="IsMouseOver"
                     Value="True">
                <Setter Property="BorderThickness"
                        Value="5" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <TextBox Text="Tesing1" Margin="146,23,0,0" Name="textBox1" Style="{StaticResource OnError}" />
    <TextBox Text="Testing2" Height="23" HorizontalAlignment="Left" Margin="12,23,0,0" Name="Test1"  VerticalAlignment="Top" Width="120" />
</Grid>

另外,在 WPF 中,您通常不使用 Margin 创建布局 :P 相反,您应该将 ColumnDefinitions 和 RowDefinitions 添加到您的 Grid,并使用 Grid.RowGrid.Column 附加属性用于指定它们在视图中的位置的文本框。

【讨论】:

  • 谢谢,有趣的是,我开始使用一种样式,但认为 ControlTemplate 是正确的 :-( 至于布局,是的,我知道表单,但这是一个临时项目,只是为了测试它,所以我没有打扰,但我会记住在发布之前整理一下。顺便说一句,你知道我是否可以按照我描述的那样为 TextBox 定义我自己的属性以用于触发目的吗?
  • 您可以扩展TextBox 类来创建您的自定义文本框,并在那里添加您的属性。或者您可以使用附加属性,这可能对您来说有点太高级了。
  • 是的,风格很好,感谢您提供有关扩展 TextBox 课程的建议并了解我们学习者的局限性,并非所有海报都让我们学习在这段旅程中行走而不准备跑步和你们……一个新的学习项目开始扩展 TextBox 类谢谢! :-)
  • 不客气!不过,只是一个提示;)如果您打算在触发器中使用新属性,则必须确保它通过 PropertyChanged 事件通知其更改(这意味着您的自定义 TextBox 必须实现 IPropertyChanged 接口)...或者使您的财产成为依赖财产,而不仅仅是普通财产。依赖属性更复杂但有很多好处,因此可能值得检查。
  • 感谢您提供的额外建议 Going For Dependency Properties 不妨舒展一下自己 :-)
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 2010-11-25
相关资源
最近更新 更多