Saf*_*ron 3 c# wpf binding controls event-handling
我只是从WPF开始,我正在尝试在局部变量和标签之间设置绑定。基本上,我想在局部变量更改时更新标签。我一直在寻找解决方案,但他们都只是将文本框用作源,而不仅仅是类变量,我甚至不确定它是否可以这种方式工作。这是我的代码。
public partial class MainWindow : Window
{
int idCounter;
public MainWindow()
{
InitializeComponent();
Binding b = new Binding();
b.Source = idCounter;
b.Mode = BindingMode.OneWay;
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
myLabel.SetBinding(Label.ContentProperty,b);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
idCounter++;
}
}
Run Code Online (Sandbox Code Playgroud)
按钮确实起作用,idCounter更改了值,但是它不会在标签中更新,因此我猜绑定是错误的。有人可以告诉我怎么了吗?谢谢
您希望使用属性来执行此操作,并实施INotifyPropertyChanged以便label在属性更改时更新 的内容。
这是一个使用简单的示例 ViewModel
xml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:converters="clr-namespace:WpfApplication1"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Label Width="200" Height="50" Content="{Binding MyLabel}"/>
<Button Height="30" Width="100" Content="Increment" Click="Button_Click" />
</StackPanel>
</Window>
Run Code Online (Sandbox Code Playgroud)
xaml.cs:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainViewModel vm = new MainViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = vm;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
vm.MyLabel += 1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
主视图模型.cs:
namespace WpfApplication1
{
public class MainViewModel : INotifyPropertyChanged
{
#region Members
private int _myLabel;
#endregion Members
#region Properties
public int MyLabel
{
get
{
return _myLabel;
}
set
{
_myLabel = value;
NotifyPropertyChanged("MyLabel");
}
}
#endregion Properties
public MainViewModel()
{
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
Run Code Online (Sandbox Code Playgroud)
注意:理想情况下,您希望使用CommandforButton而不是 Click 事件处理程序
如果您将班级更改为此,则代码将起作用。
public partial class Window1 : Window, INotifyPropertyChanged
{
private int _idCounter;
public int IdCounter
{
get { return _idCounter; }
set
{
if (value != _idCounter)
{
_idCounter = value;
OnPropertyChanged("IdCounter");
}
}
}
public Window1()
{
InitializeComponent();
myLabel.SetBinding(ContentProperty, new Binding("IdCounter"));
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
IdCounter++;
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
您遇到的一些问题是...
窗口本身应实现INotifyPropertyChanged,以便绑定引擎可以对其进行监视。
IdCounter必须是公开的,并具有公开的获取器,以便绑定引擎可以“获取”它。
您应该将DataContext设置为声明IdCounter的任何类(在这种情况下为MainWindow)。问题的一部分是绑定引擎没有DataContext。
BindingMode设置是一条红色鲱鱼,因为Label默认情况下以这种方式绑定。
UpdateSourceTrigger是一个红色鲱鱼,因为标签的内容没有更新源属性的机制。标签的内容不像文本框,用户可以在其中键入代码需要了解的内容。当您绑定到用户无法更改的内容时,请别忘了UpdateSourceTrigger,最重要的是Target属性。
处理程序应标记事件。这是一种很好的做法,并不影响绑定。
绑定构造函数仅需要路径。
该代码将为您提供预期的结果;即,单击按钮时标签会更新。在vs2013,.net 4.5上检查,编译和执行。
其他受访者表示您应该使用视图模型。我同意这一100%的要求,总的来说,这是一件好事。