【问题标题】:Why is my textbox loaded text disappearing为什么我的文本框加载的文本消失了
【发布时间】:2016-12-28 16:31:40
【问题描述】:

我有一个文本框 ACLBox,我想在用户界面初始化时显示一个字符串。初始化时,字符串闪烁一秒钟然后消失。为什么?

这是文本框的 xaml 代码:

     <Window x:Class="Funnel.ACL"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Funnel"
    mc:Ignorable="d"
    Title="ACL Configuration" Height="300" Width="560" WindowStartupLocation="CenterScreen"
    Closing="exitACL"
    Background="LightGray" Name="ACLConfiguration">

<Grid>
    <DockPanel>
        <Grid x:Name="FunnelGrid" DockPanel.Dock="Top" ShowGridLines="False">

            <!--Defining Grid-->
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="130"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="40"/>
                <ColumnDefinition Width="30"/>
                <ColumnDefinition Width="70"/>
                <ColumnDefinition Width="75"/>
                <ColumnDefinition Width="75"/>
                <ColumnDefinition Width="75"/>

            </Grid.ColumnDefinitions>

            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <Label x:Name="Config" 
                   Content="ACL CONFIGURATION" 
                   Grid.Row="0" 
                   Grid.Column="0" 
                   Grid.ColumnSpan="9" 
                   HorizontalAlignment="Center"
                   Foreground="Blue"
                   FontWeight="Heavy"
                   FontSize="16">
            </Label>
            <CheckBox x:Name="aclCheckbox" 
                      FlowDirection="RightToLeft"
                      Content="ACL ON"
                      Foreground="Blue"
                      FontWeight="Heavy"
                      FontSize="16"
                      Grid.Row="1"
                      Grid.Column="0"
                      Grid.RowSpan="1"
                      Grid.ColumnSpan="5"
                      HorizontalAlignment="Center"
                      Checked="ACL_Check"
                      Unchecked="ACL_Unchecked"
                      />

            <Label x:Name="AddIPAddress" Content="Add IP Address" Grid.Row="2" Grid.Column="0" Width="90" Height="30"></Label>
            <TextBox x:Name="AddIPTextBox1" Grid.Row="2" Grid.Column="1" Width="35" Height="20" TextChanged="AddIPTextBox1_TextChanged"></TextBox>
            <TextBox x:Name="AddIPTextBox2" Grid.Row="2" Grid.Column="2" Width="35" Height="20" TextChanged="AddIPTextBox2_TextChanged"></TextBox>
            <TextBox x:Name="AddIPTextBox3" Grid.Row="2" Grid.Column="3" Width="35" Height="20" TextChanged="AddIPTextBox3_TextChanged"></TextBox>
            <TextBox x:Name="AddIPTextBox4" Grid.Row="2" Grid.Column="4" Width="35" Height="20" TextChanged="AddIPTextBox4_TextChanged"></TextBox>
            <TextBox x:Name="AddErrorBox" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Right" BorderThickness="0" Background="LightGray" FontSize="10" Text="{Binding AddErrorText}"/>
            <Button x:Name="AddButton" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Center" Height="25" Width="50" Click="addClick" FontSize="12" FontWeight="ExtraBold" Background="LightSteelBlue"  VerticalAlignment="Top">ADD</Button>

            <Label x:Name="DelIPAddress" Content="Remove IP Address" Grid.Row="4" Grid.Column="0" Width="120" Height="30"></Label>
            <TextBox x:Name="DeleteIPTextBox1" Grid.Row="4" Grid.Column="1" Width="35" Height="20" TextChanged="DeleteIPTextBox1_TextChanged"></TextBox>
            <TextBox x:Name="DeleteIPTextBox2" Grid.Row="4" Grid.Column="2" Width="35" Height="20" TextChanged="DeleteIPTextBox2_TextChanged"></TextBox>
            <TextBox x:Name="DeleteIPTextBox3" Grid.Row="4" Grid.Column="3" Width="35" Height="20" TextChanged="DeleteIPTextBox3_TextChanged"></TextBox>
            <TextBox x:Name="DeleteIPTextBox4" Grid.Row="4" Grid.Column="4" Width="35" Height="20" TextChanged="DeleteIPTextBox4_TextChanged"></TextBox>
            <TextBox x:Name="DelErrorBox" Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Right" BorderThickness="0" Background="LightGray" FontSize="10" Text="{Binding DelErrorText}"/>
            <Button x:Name="DeleteButton" Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Center" Height="25" Width="50" Click="deleteClick" FontSize="12" FontWeight="ExtraBold" Background="LightSteelBlue"  VerticalAlignment="Top">DELETE</Button>
            <Button x:Name="DeleteAllButton" Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="4" HorizontalAlignment="Center" Height="25" Width="80" Click="deleteAllClick" FontSize="12" FontWeight="ExtraBold" Background="LightSteelBlue"  VerticalAlignment="Top">REMOVE ALL</Button>

            <Label x:Name="ACLBoxLabel" Content="Access Control List" Foreground="Blue" Grid.Row="1" Grid.Column="6" Grid.ColumnSpan="3" HorizontalAlignment="Center"></Label>

            <TextBox x:Name="ACLBox"
                 ScrollViewer.HorizontalScrollBarVisibility="Auto"
                 ScrollViewer.VerticalScrollBarVisibility="Auto"
                 ScrollViewer.CanContentScroll="True"
                 Grid.Row="2"
                 Grid.Column="6"
                 Grid.RowSpan="4"
                 Grid.ColumnSpan="4"
                 HorizontalAlignment="Left" 
                 VerticalAlignment="Center"
                 Width="220" 
                 Height="150"
                 FontSize="14"
                 IsReadOnly="True"
                 Text="{Binding ACLBoxText}"
                 TextWrapping="Wrap"
                 TextAlignment="Center" /> 
        </Grid>
    </DockPanel>
</Grid>

这是字符串的 C# 代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Funnel
{
     /// <summary>
     /// Interaction logic for ACL.xaml
     /// </summary>
     public partial class ACL : Window
     {
         AclManager _manage = new AclManager();
         FileController _controller = new FileController();
         string addStr1;
         string addStr2;
         string addStr3;
         string addStr4;
         bool addError;
    string delStr1;
    string delStr2;
    string delStr3;
    string delStr4;
    bool delError;
    public string aclText;
    public event PropertyChangedEventHandler PropertyChanged;

    public ACL()
    {
        InitializeComponent();

        if(FunnelGlobals.accessControlList)
        {
            aclCheckbox.IsChecked = true;
        }

        aclText = _manage.getAclList();
    }

    private void exitACL(object sender,System.ComponentModel.CancelEventArgs e)
    {
        _controller.writeAclFile();
    }

    private void ACL_Check(object sender, RoutedEventArgs e)
    {
        FunnelGlobals.accessControlList = true;
        aclText = _manage.getAclList();
    }

    private void ACL_Unchecked(object sender, RoutedEventArgs e)
    {
        FunnelGlobals.accessControlList = false;
        aclText = _manage.getAclList();
    }

    private void AddIPTextBox1_TextChanged(object sender, TextChangedEventArgs e)
    {
        AddErrorBox.Text = "";
        AddIPTextBox1.Text = AddIPTextBox1.Text;
        addStr1 = AddIPTextBox1.Text;
        if(!_manage.isDigit(addStr1))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            AddErrorBox.Foreground = errBrush;
            AddErrorBox.Text = "Character NOT Valid";
            addError = true;
        }
       else
        {
            addError = false;
        }
        ACLBox.Text = _manage.getAclList();
    }
    private void AddIPTextBox2_TextChanged(object sender, TextChangedEventArgs e)
    {
        AddErrorBox.Text = "";
        AddIPTextBox2.Text = AddIPTextBox2.Text;
        addStr2 = AddIPTextBox2.Text;
        if (!_manage.isDigit(addStr2))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            AddErrorBox.Foreground = errBrush;
            AddErrorBox.Text = "Character NOT Valid";
        }
        aclText = _manage.getAclList();
    }
    private void AddIPTextBox3_TextChanged(object sender, TextChangedEventArgs e)
    {
        AddErrorBox.Text = "";
        AddIPTextBox3.Text = AddIPTextBox3.Text;
        addStr3 = AddIPTextBox3.Text;
        if (!_manage.isDigit(addStr3))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            AddErrorBox.Foreground = errBrush;
            AddErrorBox.Text = "Character NOT Valid";
        }
        aclText = _manage.getAclList();
    }
    private void AddIPTextBox4_TextChanged(object sender, TextChangedEventArgs e)
    {
        AddErrorBox.Text = "";
        AddIPTextBox4.Text = AddIPTextBox4.Text;
        addStr4 = AddIPTextBox4.Text;
        if (!_manage.isDigit(addStr4))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            AddErrorBox.Foreground = errBrush;
            AddErrorBox.Text = "Character NOT Valid";
        }
        aclText = _manage.getAclList();
    }
    private void addClick(object sender, RoutedEventArgs e)
    {
        String addStr = addStr1 + "." + addStr2 + "." + addStr3 + "." + addStr4;
        if(_manage.isLegit(addStr))
        {
            FunnelGlobals.aclIPs.Add(addStr);
        }
        if(addError)
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            AddErrorBox.Foreground = errBrush;
            AddErrorBox.Text = "Fix Invalid Characters before Adding";
        }
        else
        {
            aclText = _manage.getAclList();
        }

    }

    private void DeleteIPTextBox1_TextChanged(object sender, TextChangedEventArgs e)
    {
        DelErrorBox.Text = "";
        DeleteIPTextBox1.Text = DeleteIPTextBox1.Text;
        delStr1 = DeleteIPTextBox1.Text;
        if (!_manage.isDigit(delStr1))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            DelErrorBox.Foreground = errBrush;
            DelErrorBox.Text = "Character NOT Valid";
            delError = true;
        }
        else
        {
            delError = false;
        }
    }

    private void DeleteIPTextBox2_TextChanged(object sender, TextChangedEventArgs e)
    {
        DelErrorBox.Text = "";
        DeleteIPTextBox2.Text = DeleteIPTextBox2.Text;
        delStr2 = DeleteIPTextBox2.Text;
        if (!_manage.isDigit(delStr2))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            DelErrorBox.Foreground = errBrush;
            DelErrorBox.Text = "Character NOT Valid";
            delError = true;
        }
        else
        {
            delError = false;
        }
    }

    private void DeleteIPTextBox3_TextChanged(object sender, TextChangedEventArgs e)
    {
        DelErrorBox.Text = "";
        DeleteIPTextBox3.Text = DeleteIPTextBox3.Text;
        delStr3 = DeleteIPTextBox3.Text;
        if (!_manage.isDigit(delStr3))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            DelErrorBox.Foreground = errBrush;
            DelErrorBox.Text = "Character NOT Valid";
            delError = true;
        }
        else
        {
            delError = false;
        }
    }

    private void DeleteIPTextBox4_TextChanged(object sender, TextChangedEventArgs e)
    {
        DelErrorBox.Text = "";
        DeleteIPTextBox4.Text = DeleteIPTextBox4.Text;
        delStr4 = DeleteIPTextBox4.Text;
        if (!_manage.isDigit(delStr4))
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            DelErrorBox.Foreground = errBrush;
            DelErrorBox.Text = "Character NOT Valid";
            delError = true;
        }
        else
        {
            delError = false;
        }
    }

    private void deleteClick(object sender, RoutedEventArgs e)
    {
        String delStr = delStr1 + "." + delStr2 + "." + delStr3 + "." + delStr4;
        FunnelGlobals.aclIPs.Remove(delStr);

        if (delError)
        {
            Color foreColor = (Color)new ColorConverter().ConvertFrom("red");
            Brush errBrush = new SolidColorBrush(foreColor);
            DelErrorBox.Foreground = errBrush;
            DelErrorBox.Text = "Fix Invalid Characters before Removing";
        }
        else
        {
            aclText = _manage.getAclList();  
        }
    }

    private void deleteAllClick(object sender, RoutedEventArgs e)
    {
        FunnelGlobals.aclIPs.Clear();
        aclText = _manage.getAclList();
    }

    private void ACLBox_Loaded(object sender, RoutedEventArgs e)
    {
      ACLBox.Text = _manage.getAclList();
    }
    public string ACLBoxText
    {
        get { return aclText; }
        set { aclText = value; OnNotifyPropertyChanged("ACLBoxText"); }
    }

    private void OnNotifyPropertyChanged(string v)
    {
        var handler = PropertyChanged;

        if (handler != null)
            handler(this, new PropertyChangedEventArgs(v));
        throw new NotImplementedException();
    }
}

}

【问题讨论】:

  • ACLBoxText 为空或为空,对吗?为什么要在 Loaded 事件中绑定视图模型属性初始化ACLBox.Text?不要那样踩自己。绑定ACLBoxText(您已经这样做了),并初始化ACLBoxText 以初始化文本框中的内容。如果要绑定 viewmodel 属性,只需使用该属性。摆脱那个 Loaded 处理程序。这可能是错的;试试看是否还有问题。
  • 仅通过binding 或仅通过后面的代码设置Text 属性。当您在后面的代码中设置 property 时,binding 会损坏。
  • 我希望文本来自用户可以更新的列表...随意添加或删除。当用户转到列表配置时,我希望文本框显示此列表。它在文本框中闪烁一秒钟然后消失。然后,如果您向其中添加列表,则会出现并保留。除了现在我从下面的 cmets 添加了一些代码之外,我正在以完全相同的方式进行这两种操作。代码仍然消失。我看不出它在代码中的哪个位置可以被覆盖。使用 Visual Studio,我查看了 ACLBox.Text 的每个实现,它始终设置为 _manage.getAclList();

标签: c# wpf data-binding


【解决方案1】:

初始化时,字符串会闪烁一秒钟然后消失。为什么?

可能是因为当您在 Loaded 事件处理程序中设置 TextBlock 的 Text 属性时,您正在“覆盖”最初显示在 TextBlock 中的 ACLBoxText 源属性的值。

如果加载 UI 后 TextBlock 为空,则应确保 _manage.getAclList() 方法返回您期望它返回的字符串。您可以暂时尝试将 Text 属性分配给“静态”值:

private void ACLBox_Loaded(object sender, RoutedEventArgs e)
{
    ACLBox.Text = "TEXT";
}

但我同意,首先将 TextBlock 的 Text 属性绑定到 XAML 标记中的源属性,然后处理同一 TextBlock 的 Loaded 事件并将其 Text 属性设置为新值并没有多大意义在这个事件处理程序中。但我猜你有你的理由......

请注意,当您以编程方式在 Loaded 处理程序中设置 Text 属性时,您在 XAML 标记中定义的绑定将被重置。

因此,您不应该在 XAML 标记中绑定 Text 属性,或者不处理 Loaded 事件并以编程方式设置 Text 属性。这是其中之一,但不是两者兼而有之。

【讨论】:

  • 如果我有一个静态字符串值,那么它也会出现和消失。我没有看到任何会覆盖该值的代码。
  • Loaded 事件中的代码怎么样?这会覆盖初始值。
  • 加载的事件与初始值相同。如果没有加载的事件,在您添加另一个 IP 地址之前,框中不会出现任何内容。然后整个列表加上新 IP 出现在文本框中。
【解决方案2】:

我发现了问题所在。这是我的第一个 C# 项目,也是第一次使用 Xaml (wpf),所以我误解了绑定。我像在主 gui 中那样绑定文本。文本永远不会在此 gui 中触发,因此由于已加载,我只能看到文本闪烁,但随后文本绑定将文本框重置为空。当我将文本更改为不受约束时,一切都会按我的意愿进行。学过的知识。仅当从 .cs 文件中访问文本框时才需要绑定。在 xaml.cs 中不需要它。由于我的文本只会由 xaml.cs 触发,因此只需按通常的方式设置文本(即 textbox.text = “whatever”)就可以满足我的需要。感谢大家的帮助。我现在理解绑定好多了。 Java 做的事情不同。 :)

【讨论】:

    【解决方案3】:

    正如 Ed Plunkett 已经提到的,您应该使用您的 ACLBoxText 支持变量而不是重置控制值。

    这样的事情会起作用:

    private void ACLBox_Loaded(object sender, RoutedEventArgs e)
    {
         ACLBoxText = _manage.getAclList();
    }
    

    不幸的是,视图不知道支持属性的变化,除非你告诉它发生了变化。你需要实现INotifyPropertyChanged

    private string _aclBoxText;
    
    public string ACLBoxText {
        get { return _aclBoxText; }
        set {
            _aclBoxText = value;
            OnNotifyPropertyChanged("ACLBoxText");
        }
    }
    
    protected void OnNotifyPropertyChanged(string name)
    {
        var handler = PropertyChanged;
    
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(name));
    }
    
    public event PropertyChangedEventHandler PropertyChanged;
    

    【讨论】:

    • 如果 OP 将视图变成一个假的视图模型 并且 设置 this.DataContext = this;,类似的事情会起作用,尽管这不是一个好方法。但我认为您需要首先找出ACLBoxText 的具体内容(如果有的话)。如果有视图模型,OP 当然不应该丢弃它并像这样重新开始。
    • 我添加了通知,同样的事情发生了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多