2015-04-22 5 views
1

Предупреждение: Я полный WPF noob, исходящий из фона форм Windows.Textbox.Text не обновляется в WPF

У меня есть UserFontrol WPF, который, в свою очередь, содержит несколько других UserControls, каждый из которых предназначен для отображения определенного фрагмента данных из файла пользователя. Один из этих элементов управления просто показывает имя, адрес и идентификатор клиента.

Итак, мой главный управляющий выглядит так:

<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 нового, который загружает данные из файла.

Это 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 я просто изменяю значения (pDebtor.tbName.Text = "Dummy") в коде для элемента управления FileView, он отлично работает.

Что мне здесь не хватает? Разве я не могу заменить существующий элемент управления новым таким образом?

Я попытался установить свой оригинальный pnlDebtor в значение null до установки нового элемента управления, но получил те же результаты. Как-то мой контроль заменяется, но никогда не отправляется в графический интерфейс.

+1

Вам необходимо прочитать [Обзор привязки данных] (https://msdn.microsoft.com/en-us/library/ms752347 (v = vs.110).aspx) и интерфейс '' INotifyPropertyChanged '' (https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged (v = vs.110) .aspx) в MSDN. – Sheridan

ответ

1

В то время как вы можете создавать элементы управление из кода, вы должны перестать думать в том, что Windows Forms способ создания пользовательского интерфейса, а также узнать больше о том, как WPF работает в general и о data binding.

В принципе, вам нужно привязать значение текстового поля к строковому свойству, а затем использовать код только для установки значений этих свойств, привязка позаботится об остальном и обновит пользовательский интерфейс для вас.

+0

Он отлично работает. Спасибо. Когда я дал свой pnlDebtor свойство DebtorName и установил свойство Text моего tbName: 'Text =" {Binding RelativeSource = {RelativeSource FindAncestor, AncestorType = my: pnlDebtor, AncestorLevel = 1}, Path = DebtorName, Mode = OneWay} "' Все было обработано для меня. Не нужно внедрять INotifyPropertyChanged Меня беспокоит, что привязка выполняется в XAML вместо кода. Меня также беспокоит, что если я установил точку останова, свойство pnlDebtor.tbName.Text останется пустым. –

+0

Кроме того, вместо создания нового pnlDebtor я сохраняю существующий элемент управления и просто назначаю файл свойству существующего элемента управления. –

+1

Чтобы быть честным, вы должны попытаться использовать свойство, я знаю, что это странно происходит от WinForms, но как только вы увидите преимущества, вы начнете их оценивать. Например, при работе в команде он позволяет полностью отделить дизайн пользовательского интерфейса от модели, поэтому человеку, разрабатывающему интерфейс, нужно знать только имена свойств и не беспокоить фактическую реализацию кода. Приводит к гораздо более легкому и понятному дизайну интерфейса. –

0

Похоже, вы хотите использовать привязку данных. Вы можете указать контекст данных для привязки в 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" /> 

В вашем контакте класс вам необходимо реализовать INotifyPropertyChanged или использовать базовый пример, например https://stackoverflow.com/a/1316417/2622972. После этого добавьте свойство strName, которое вызывает вашу версию, но вы выполняете INotifyPropertyChanged.

Смежные вопросы