2012-11-10 9 views
6

Chcę, aby pole tekstowe wyświetlało wartość zmiennej po jej kliknięciu (iteracja od 1 do 100), nie wiem, co robię Wrong :Nie mogę powiązać danych z lokalną zmienną w WPF/XAML

Po uruchomieniu projektu nic nie jest wyświetlane w polu tekstowym.

Jaki jest najlepszy sposób wyświetlania zmiennych w polu tekstowym?

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

namespace dataBindingTest 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     public string myText { get; set; } 

     public void Button_Click_1(object sender, RoutedEventArgs e) 
     { 
      int i = 0; 
      for (i = 0; i < 100; i++) 
      { 
       myText = i.ToString(); 
      } 
     } 
    } 
} 

XAML:

<Window x:Class="dataBindingTest.MainWindow" 
     Name="windowElement" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Button Content="Button" HorizontalAlignment="Left" Height="106" Margin="71,95,0,0" VerticalAlignment="Top" Width="125" Click="Button_Click_1"/> 
     <TextBlock x:Name="myTextBox" HorizontalAlignment="Left" Height="106" Margin="270,95,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="187" Text= "{Binding myText, ElementName=windowElement}" /> 

    </Grid> 
</Window> 
+0

Należy badania wzorca MVVM. Powiązanie WPF reaguje na właściwości obiektów, które implementują interfejs INotifyPropertyChanged.Struktury MVVM, takie jak Mvvmlight (dostępne na NuGet), wykonują dobrą robotę, zapewniając łatwe w użyciu klasy bazowe dla ViewModels i RelayCommands –

Odpowiedz

10

Własna właściwość myText nie ma możliwości powiadomienia systemu powiązań WPF, gdy jej wartość uległa zmianie, więc TextBlock nie będzie aktualizowany.

Jeśli zamiast tego zostanie użyta właściwość zależności, automatycznie zrealizuje powiadomienie o zmianie, a zmiany w obiekcie zostaną odzwierciedlone w TextBlock.

Więc jeśli zastąpić public string myText { get; set; } z tym wszystkim kod powinien działać:

public string myText 
{ 
    get { return (string)GetValue(myTextProperty); } 
    set { SetValue(myTextProperty, value); } 
} 

// Using a DependencyProperty as the backing store for myText. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty myTextProperty = 
    DependencyProperty.Register("myText", typeof(string), typeof(Window1), new PropertyMetadata(null)); 
+0

To zadziałało, dziękuję .. – mzachen

1

Należy wdrożyć INotifyPropertyChanged w swoim "MainWindow" więc "myTextBlock" może automatycznie odebrać zmiany w swoich danych i aktualizacji.

Więc „MainWindow” powinna wyglądać następująco:

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 
    private string _myText; 

    public string myText { 
     get{return _myText;} 
     set{_myText = value; 
     if(PropertyChanged!=null) PropertyChanged(this, new PropertyChangedEventArgs("myText")) ; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    etc..... 
} 
0

Trzeba uczynić właściwość wiązania powiedzieć, że został zaktualizowany. Standardowym sposobem na to jest poprzez:

  1. Wdrażanie INotifyPropertyChanged
  2. Making właściwość myText DependencyProperty
  3. Innym może mniej używane sposobem jest ręcznie podnieść zdarzenia, na przykład:
public void Button_Click_1(object sender, RoutedEventArgs e) 
{ 
    myText = "Clicked"; 
    BindingOperations.GetBindingExpressionBase(myTextBox, TextBlock.TextProperty).UpdateTarget(); 
} 

Pamiętaj, że Twój TextBlock ma mylącą nazwę: myTextBox

3

Spróbuj tego:

public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
     } 

     public string myText { get; set; } 

     public void Button_Click_1(object sender, RoutedEventArgs e) 
     { 
      BackgroundWorker bw = new BackgroundWorker(); 
      bw.DoWork += delegate 
      { 
       int i = 0; 
       for (i = 0; i < 100; i++) 
       { 
        System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() => { myText = i.ToString(); OnPropertyChanged("myText"); }));      
        Thread.Sleep(100); 
       } 
      }; 

      bw.RunWorkerAsync(); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string name) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(name)); 
      } 
     } 
    } 

plik XAML:

<Grid> 
      <Button Content="Button" HorizontalAlignment="Left" Height="106" Margin="71,95,0,0" VerticalAlignment="Top" Width="125" Click="Button_Click_1"/> 
      <TextBlock x:Name="myTextBox" 
         HorizontalAlignment="Right" Height="106" Margin="0,95,46,0" 
         TextWrapping="Wrap" VerticalAlignment="Top" Width="187" 
         Text= "{Binding myText}" /> 

     </Grid> 
7

wdrożyć INotifyPropertyChanged:

public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     public MainWindow() 
     { 
      this.InitializeComponent(); 
     } 

     private string _txt; 
     public string txt 
     { 
      get 
      { 
       return _txt; 
      } 
      set 
      { 
       if (_txt != value) 
       { 
        _txt = value; 
        OnPropertyChanged("txt"); 
       } 
      } 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      txt = "changed text"; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

XAML:

<TextBox Text="{Binding txt}"/> 
<Button Click="Button_Click">yes</Button> 

i nie zapomnieć o dodaniu właściwość DataContext okna:

<Window ... DataContext="{Binding RelativeSource={RelativeSource Self}}"/> 
+0

Wreszcie coś, co działa! –

Powiązane problemy