Textbox.Text 未在 WPF 中更新

Textbox.Text not updating in WPF

警告:我是一个完整的 WPF 新手,来自 Windows 表单背景。

我有一个 WPF UserControl,它又包含其他几个 UserControl,每个 UserControl 都用于显示用户文件中的特定数据块。这些控件之一仅显示姓名、地址和客户 ID。

所以,我的主控件是这样的:

<UserControl x:Class="Plus.Gui.FileView"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="800" d:DesignWidth="1200" 
             xmlns:gui="clr-namespace:Plus.Gui">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="150*" />
            <RowDefinition Height="150*" />
            <RowDefinition Height="200*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="488*" />
            <ColumnDefinition Width="260*" />
            <ColumnDefinition Width="252*" />
        </Grid.ColumnDefinitions>
        <gui:pnlDebtor Grid.Column="2" HorizontalAlignment="Stretch" x:Name="pDebtor" VerticalAlignment="Stretch" />
    </Grid>
</UserControl>

pnlDebtor 控件应该显示我的信息。

我的主控件的代码隐藏如下所示:

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.Navigation;
using System.Windows.Shapes;
using MyDataLayer;

namespace Plus.Gui
{
    public partial class FileView : UserControl
    {
        public FileView()
        {
            InitializeComponent();
        }

        public FileView(MyCase file)
        {
            InitializeComponent();
            pDebtor = new pnlDebtor(file);
        }
    }
}

我正在用一个从文件加载数据的新 pnlDebtor 替换我的默认 pnlDebtor。

这是 xaml 和我的 pnlDebtor 控件的部分代码隐藏。

<UserControl x:Class="Plus.Gui.pnlDebtor"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="230" d:DesignWidth="460">
    <Grid>
        <GroupBox Header="Debtor" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="groupBox1" VerticalAlignment="Stretch">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="28" />
                    <RowDefinition Height="56" />
                    <RowDefinition Height="28" />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="80*" />
                    <ColumnDefinition Width="380*" />
                </Grid.ColumnDefinitions>
                <Label Content="Name:" Height="28" HorizontalAlignment="Left" Name="lblName" VerticalAlignment="Top" />
                <Label Content="Address:" Grid.Row="1" Height="28" HorizontalAlignment="Left" Name="lblAddress" VerticalAlignment="Top" />
                <Label Content="Customer Nr.:" Grid.Row="2" Height="28" HorizontalAlignment="Left" Name="lblCustomerNr" VerticalAlignment="Top" />
                <TextBox Grid.Column="1" Height="23" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="tbName" VerticalAlignment="Top" IsEnabled="False" IsReadOnly="False" />
                <TextBox Grid.Column="1" Grid.Row="1" Height="46" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="tbAddress" VerticalAlignment="Top" IsReadOnly="False" IsEnabled="True" />
                <TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="tbCustomerNr" VerticalAlignment="Top" IsEnabled="True" IsReadOnly="False" />
                <Button Content="Debtor Details" Grid.ColumnSpan="2" Grid.Row="3" Height="23" HorizontalAlignment="Left" Margin="0,0,0,0" Name="btnDetails" VerticalAlignment="Top" />
            </Grid>
        </GroupBox>
    </Grid>
</UserControl>

public pnlDebtor(MyCase file)
{
    InitializeComponent();
    Contact con = AbstractDataObject.GetObject4ID<Contact>(file.DebtorID);
    string strName = con.Name1;

    if (con.Name2 != null)
        strName += " " + con.Name2;

    if (con.Name3 != null)
        strName += " " + con.Name3;

    if (con.FirstName != null)
        strName += ", " + con.FirstName;

    tbName.Text = strName;
    tbAddress.Text = "test address";
    tbCustomerNr.Text = "test customer id";
}

所以,基本上,我传入文件并使用文件中的信息更新文本框。简单的。只是,没用。

如果我在创建新的pnlDebtor后设置断点,并查看属性,tbName.Text、tbAddress.Text和tbCustomerNr.Text确实被改变了。但是在gui中所有的框都是空的。

如果我没有分配新的 pnlDebtor,而是简单地更改 FileView 控件的代码隐藏中的值 (pDebtor.tbName.Text = "Dummy"),它工作正常。

我在这里错过了什么?我不能用这种方式用新控件替换现有控件吗?

我试过在设置新控件之前将我原来的 pnlDebtor 设置为 null,但得到了相同的结果。我的控件以某种方式被替换,但从未发送到 GUI。

您似乎想使用数据绑定。您可以在 xaml 中指定用于绑定的数据上下文,或者要使其与您现有的代码相似,您可以在后面的代码中执行此操作:

DataContext = AbstractDatenObjekt.GetObjekt4ID<Contact>(file.DebtorID);

XAML:

<TextBox Text="{Binding strName, Mode=TwoWay}" Grid.Column="1" Height="23" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="tbName" VerticalAlignment="Top" IsEnabled="False" IsReadOnly="False" />

在您的联系人 class 中,您需要实施 INotifyPropertyChanged 或使用像 这样的基本案例。一旦你有了它,为 strName 添加一个 属性 来调用你的 INotifyPropertyChanged 版本。

虽然您可以从代码创建控件,但您应该停止思考 Windows 创建 UI 的形式,并阅读有关 WPF 的更多信息在 general and about data binding.

工作

基本上,您需要将文本框值绑定到字符串 属性,然后仅使用代码设置这些属性的值,绑定将处理其余部分并更新 UI给你。