我正在尝试WPF绑定。我写了小应用程序,但有问题,我的UI没有更新。这是我的代码:
<Grid>
<Button Content="Button" HorizontalAlignment="Left" Margin="345,258,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<TextBox x:Name="text" HorizontalAlignment="Left" Height="23" Margin="75,165,0,0" TextWrapping="Wrap" Text="{Binding Path=Count}" VerticalAlignment="Top" Width="311"/>
</Grid>
代码隐藏:
namespace WpfApplication1
{
public partial class MainWindow : Window
{
MyClass mc;
public MainWindow()
{
InitializeComponent();
mc = new MyClass(this.Dispatcher);
text.DataContext = mc;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Task task = new Task(() =>
{
mc.StartCounting();
});
task.ContinueWith((previousTask) =>
{
},
TaskScheduler.FromCurrentSynchronizationContext());
task.Start();
}
}
public class MyClass
{
public int Count { get; set; }
public Dispatcher MainWindowDispatcher;
public MyClass(Dispatcher mainWindowDispatcher)
{
MainWindowDispatcher = mainWindowDispatcher;
}
public void StartCounting()
{
while (Count != 3)
{
MainWindowDispatcher.Invoke(() =>
{
Count++;
});
}
}
}
}
问题是什么我是否正确地写了这个,有没有更好的方法来做到这一点?
答案 0 :(得分:3)
为了支持双向WPF DataBinding,您的数据类必须Implement the INotifyPropertyChanged
interface。
首先,创建一个可以通过将它们编组到UI线程来通知属性更改的类:
public class PropertyChangedBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
Application.Current.Dispatcher.BeginInvoke((Action) (() =>
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}));
}
}
然后,让MyClass
继承此内容并在Count
属性发生更改时正确提出属性更改通知:
public class MyClass: PropertyChangedBase
{
private int _count;
public int Count
{
get { return _count; }
set
{
_count = value;
OnPropertyChanged("Count"); //This is important!!!!
}
}
public void StartCounting()
{
while (Count != 3)
{
Count++; //No need to marshall this operation to the UI thread. Only the property change notification is required to run on the Dispatcher thread.
}
}
}