【问题标题】:textbox not being reset despite the fact that property to which it is bound being set to null文本框没有被重置,尽管它绑定的属性被设置为 null
【发布时间】:2020-03-19 19:22:59
【问题描述】:

我在一个表单上有一个文本框,它的文本属性没有被重置,尽管它绑定的字符串属性被设置为空。访问由表单上另一个名为 cbxPartIINA 的复选框控制。当检查CBXPartiina时,应该禁用文本框并将其清空。当我检查 cbxPartIINA 时,文本框被禁用,但没有空白。

这是文本框的 XAML:

    <TextBox Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" MaxLength="25" 
                        MinWidth="200" CharacterCasing="Upper" BorderThickness="0" Style="{StaticResource PartIIGridIsEnabledTextBox}"
                        Margin="5,2,0,3" FontWeight="Bold" Name="tbxNewSuspectLastName" 
                        Text="{Binding Form104CModel.NewSuspectLastName, Mode=TwoWay}"/>

这里是静态资源:

       <Style TargetType="TextBox" x:Key="PartIIGridIsEnabledTextBox">
            <!-- This style is used to turn off TextBoxes in Part II-->
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=cbxPartIINA}" Value="False">
                    <Setter Property="IsEnabled" Value="True"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding IsChecked, ElementName=cbxPartIINA}" Value="True">
                    <Setter Property="IsEnabled" Value="False"/>
                    <Setter Property="Text" Value=""/>
                </DataTrigger>
            </Style.Triggers>
            <Setter Property="FontWeight" Value="Bold"></Setter>
        </Style>

这是复选框的 XAML,选中后会关闭文本框:

 <CheckBox Grid.Column="1" Content="NA" Background="White" Height="20" Width="auto" BorderBrush="Black" Name="cbxPartIINA" 
                          IsChecked="{Binding Path=Form104CModel.IsPartIINA, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

这是 textbox.text 绑定到的属性:

    private String newsuspectlastname;
    public String NewSuspectLastName
    {
        get
        {
            return this.newsuspectlastname;
        }
        set
        {
            this.newsuspectlastname = value;
            this.NewSuspect.LastName = value;
        }
    }

尽管绑定是双向的并且基础属性 NewSuspectLastName 被设置为 null,但 textbox.text 属性并未被重置。

【问题讨论】:

    标签: c# xaml


    【解决方案1】:

    WPF 使用 INotifyPropertyChanged 来监控底层模型的变化。

    您需要在您的模型上实现 INotofyPropertyChanged,如下所示:

    public class MyModel: INotifyPropertyChanged  
    {
        public event PropertyChangedEventHandler PropertyChanged;  
    
        // This method is called by the Set accessor of each property.  
        // The CallerMemberName attribute that is applied to the optional propertyName  
        // parameter causes the property name of the caller to be substituted as an argument.  
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")  
        {  
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }  
    
        private String newsuspectlastname;
        public String NewSuspectLastName
        {
            get
            {
                return this.newsuspectlastname;
            }
            set
            {
                if (value != this.newsuspectlastname )  
                 {  
                     this.newsuspectlastname = value;
                     this.NewSuspect.LastName = value;
                     NotifyPropertyChanged();  
                }  
    
            }
        }
    }
    

    【讨论】:

    • INotifyProperty changed 在我的模型继承的类中实现,这意味着它已经通过继承在我的模型中实现。但是谢谢你的回答。问题已解决。问题是我在对象上设置了 text 属性的绑定,然后尝试在样式中重置它。对 WPF 有点陌生,我不知道。真正让我失望的是该技术适用于 IsEnabled 属性和 ComboBoxes。
    • 那么您发布的代码没有使用 INotifyPropertyChanged。每当属性更改时,您都需要触发事件。而你的代码并没有这样做
    • 换句话说,每个属性设置器都必须触发 PropertyChange 事件。否则 WPF 引擎永远不会知道属性已更改
    • 谢谢。最后一部分是我必须记住的。
    【解决方案2】:

    这是因为您在对象级别而不是样式级别设置了文本绑定。直接在对象上设置属性总是会优先于 Style 设置的值。为了实现您所需要的,您只需将绑定移动到样式,如下所示:

    <Style TargetType="TextBox" x:Key="PartIIGridIsEnabledTextBox">
        <!-- This style is used to turn off TextBoxes in Part II-->
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsChecked, ElementName=cbxPartIINA}" Value="False">
                <Setter Property="IsEnabled" Value="True"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsChecked, ElementName=cbxPartIINA}" Value="True">
                <Setter Property="IsEnabled" Value="False"/>
                <Setter Property="Text" Value=""/>
            </DataTrigger>
        </Style.Triggers>
        <Setter Property="FontWeight" Value="Bold"></Setter>
        <Setter Property="Text" Value="{Binding Form104CModel.NewSuspectLastName, Mode=TwoWay}"/>
    </Style>
    

    您的文本框将如下所示:

    <TextBox Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" MaxLength="25" MinWidth="200" CharacterCasing="Upper" BorderThickness="0" Style="{StaticResource PartIIGridIsEnabledTextBox}" Margin="5,2,0,3" FontWeight="Bold" Name="tbxNewSuspectLastName"/>
    

    【讨论】:

    • 我无法在样式级别设置绑定,因为多个文本框使用此样式,因此它们都将绑定到同一个属性。我会试一试,但我必须更改键,以便只有我的姓氏文本框使用该样式。当属性 IsPartIINA 设置为 true(它是一个布尔值)时,我什至尝试将 NewSuspectLastName 属性设置为 null,我认为与文本框的双向绑定会启动,但这也不起作用。
    • 谢谢。你帮助修复了它。我只是在对象级别设置样式,然后将绑定移动到对象级别的样式中。我猜使用静态资源有其局限性。
    • 很高兴能帮上忙!
    猜你喜欢
    • 2013-11-26
    • 2013-10-03
    • 2020-12-19
    • 2013-05-12
    • 2018-10-24
    • 1970-01-01
    • 2020-09-16
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多