我有一个具有相当长的运行过程的类,我希望GUI能够取得进展。
该类有一个名为Progress的属性,它是一个实现INotifyPropertyChanged的类。我正在使用BusyWorker并将类的Progress属性绑定到它的datacontext,但只要进度发生变化,BusyWorker就不会显示任何内容。我不知道我在这里是否有任何意义,所以这里有一些代码:
有问题的课程:
public class MyClass
{
public Progress MyProgress { get; set; }
public void Run()
{
MyProgress = new Progress();
MyProgress.Status = "Initialising";
// Do stuff, update progress, etc.
}
}
public class Progress : INotifyPropertyChanged
{
private string status;
public string Status
{
get { return status; }
set
{
status = value;
OnPropertyChanged("Status");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
XAML:
// ...
<xctk:BusyIndicator HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="busyIndicator" VerticalAlignment="Stretch" BusyContent="{Binding}">
<xctk:BusyIndicator.BusyContentTemplate>
<DataTemplate>
<StackPanel Margin="4">
<TextBlock Text="{Binding Status}" FontWeight="Bold" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
</xctk:BusyIndicator.BusyContentTemplate>
</xctk:BusyIndicator>
// ...
XAML.CS:
MyClass test = new MyClass();
BusyIndicator.DataContext = test.MyProgress;
BusyIndicator.IsBusy = true;
test.Run();
如果我这样运行,并在OnPropertyChanged
电话停留,PropertChanged
始终为空。如果我在我的xaml.cs中创建一个单独的Progress对象,它可以正常工作,但我希望我的'Run'方法来处理它。这甚至可能吗?
答案 0 :(得分:2)
问题是你在调用run方法之前分配数据上下文,这意味着当你分配数据上下文时“MyProgress”对象是“Null”..所以在调用“Run”方法之前数据上下文为null。你正在调用Run方法,它为“MyProgress”创建一个实例,但由于你的“MyClass”不是“INotifyPropertyChanged”,它无法通知数据上下文更改......
解决方法是:尝试在MyClass的构造函数中创建MyProgress实例..所以在分配数据时,上下文不会为null,并且在run方法中不创建任何实例只需更新status属性..
像这样的东西
public class MyClass
{
public Progress MyProgress { get; set; }
public MyClass()
{
MyProgress = new Progress();
}
public void Run()
{
MyProgress.Status = "Initialising";
// Do stuff, update progress, etc.
}
}
答案 1 :(得分:0)
<xctk:BusyIndicator HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="busyIndicator" VerticalAlignment="Stretch" BusyContent="{Binding}">
<xctk:BusyIndicator.BusyContentTemplate>
<DataTemplate>
<StackPanel Margin="4">
<TextBlock Text="{Binding Path=Status}" FontWeight="Bold" HorizontalAlignment="Left" DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=BusyIndicator}}"/>
</StackPanel>
</DataTemplate>
</xctk:BusyIndicator.BusyContentTemplate>
// ...
答案 2 :(得分:0)
这对我有用:
*的.xaml
<xctk:BusyIndicator HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="busyIndicator" VerticalAlignment="Stretch" IsBusy="True">
<xctk:BusyIndicator.BusyContentTemplate>
<DataTemplate>
<StackPanel Margin="4">
<TextBlock Text="{Binding Path=Test.MyProgress.Status, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" FontWeight="Bold" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
</xctk:BusyIndicator.BusyContentTemplate>
</xctk:BusyIndicator>
* xaml.cs:
public partial class MainWindow : Window
{
public MyClass Test { get; set; }
public MainWindow()
{
Test = new MyClass();
InitializeComponent();
Test.Run();
}
}
public class MyClass
{
public Progress MyProgress { get; set; }
public void Run()
{
MyProgress = new Progress();
MyProgress.Status = "Initialising";
// Do stuff, update progress, etc.
}
}
public class Progress : INotifyPropertyChanged
{
private string status;
public string Status
{
get { return status; }
set
{
status = value;
OnPropertyChanged("Status");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string info)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}