我无法将数据绑定到WPF / XAML中的局部变量

时间:2022-06-10 20:54:08

I want a textbox to display the value of a variable when I click it (an iteration of 1 to 100), I do not know what I am doing Wrong:

我想要一个文本框在我点击它时显示变量的值(1到100的迭代),我不知道我在做什么错了:

When I run the project nothing is displayed in the text box.

当我运行项目时,文本框中不显示任何内容。

What is the best way to display variables in a text box?

在文本框中显示变量的最佳方法是什么?

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:

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>

5 个解决方案

#1


10  

Your current myText property has no way of notifying the WPF binding system when its value has changed, so the TextBlock wont be updated.

您的当前myText属性无法在其值发生更改时通知WPF绑定系统,因此TextBlock不会更新。

If you make it a dependency property instead it automatically implements change notification, and the changes to the property will be reflected in the TextBlock.

如果将其设为依赖项属性,则会自动实现更改通知,并且对属性的更改将反映在TextBlock中。

So if you replace public string myText { get; set; } with all of this code it should work:

所以如果你替换公共字符串myText {get;组;使用所有这些代码它应该工作:

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));

#2


7  

implement INotifyPropertyChanged:

实现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:

XAML:

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

and don't forget about adding the DataContext property of your window:

并且不要忘记添加窗口的DataContext属性:

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

#3


3  

Try this:

尝试这个:

 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));
            }
        }
    }

XAML file:

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>

#4


1  

You should implement INotifyPropertyChanged in your "MainWindow" so your "myTextBlock" can automatically pick up changes from your data and update.

您应该在“MainWindow”中实现INotifyPropertyChanged,这样您的“myTextBlock”就可以自动从您的数据中获取更新并进行更新。

So your "MainWindow" should look like:

所以你的“MainWindow”应该是这样的:

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.....
}

#5


0  

You need to make the property tell the binding that it has updated. The standard way to do this is via:

您需要使属性告诉它已更新的绑定。执行此操作的标准方法是:

  1. Implementing INotifyPropertyChanged
  2. 实现INotifyPropertyChanged
  3. Making the myText property a DependencyProperty
  4. 使myText属性成为DependencyProperty
  5. Another maybe less used way is to raise the event manually, like this:
  6. 另一种可能不太常用的方法是手动引发事件,如下所示:
public void Button_Click_1(object sender, RoutedEventArgs e)
{
    myText = "Clicked";
    BindingOperations.GetBindingExpressionBase(myTextBox, TextBlock.TextProperty).UpdateTarget();
}

Note that your TextBlock has the confusing name myTextBox

请注意,您的TextBlock具有令人困惑的名称myTextBox

#1


10  

Your current myText property has no way of notifying the WPF binding system when its value has changed, so the TextBlock wont be updated.

您的当前myText属性无法在其值发生更改时通知WPF绑定系统,因此TextBlock不会更新。

If you make it a dependency property instead it automatically implements change notification, and the changes to the property will be reflected in the TextBlock.

如果将其设为依赖项属性,则会自动实现更改通知,并且对属性的更改将反映在TextBlock中。

So if you replace public string myText { get; set; } with all of this code it should work:

所以如果你替换公共字符串myText {get;组;使用所有这些代码它应该工作:

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));

#2


7  

implement INotifyPropertyChanged:

实现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:

XAML:

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

and don't forget about adding the DataContext property of your window:

并且不要忘记添加窗口的DataContext属性:

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

#3


3  

Try this:

尝试这个:

 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));
            }
        }
    }

XAML file:

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>

#4


1  

You should implement INotifyPropertyChanged in your "MainWindow" so your "myTextBlock" can automatically pick up changes from your data and update.

您应该在“MainWindow”中实现INotifyPropertyChanged,这样您的“myTextBlock”就可以自动从您的数据中获取更新并进行更新。

So your "MainWindow" should look like:

所以你的“MainWindow”应该是这样的:

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.....
}

#5


0  

You need to make the property tell the binding that it has updated. The standard way to do this is via:

您需要使属性告诉它已更新的绑定。执行此操作的标准方法是:

  1. Implementing INotifyPropertyChanged
  2. 实现INotifyPropertyChanged
  3. Making the myText property a DependencyProperty
  4. 使myText属性成为DependencyProperty
  5. Another maybe less used way is to raise the event manually, like this:
  6. 另一种可能不太常用的方法是手动引发事件,如下所示:
public void Button_Click_1(object sender, RoutedEventArgs e)
{
    myText = "Clicked";
    BindingOperations.GetBindingExpressionBase(myTextBox, TextBlock.TextProperty).UpdateTarget();
}

Note that your TextBlock has the confusing name myTextBox

请注意,您的TextBlock具有令人困惑的名称myTextBox