0

我有一个类有一个相当长的运行过程,我希望 GUI 能够取得进展。

该类有一个名为 Progress 的属性,它是一个实现 INotifyPropertyChanged 的​​类。我正在使用 BusyWorker 并将类的 Progress 属性绑定到它的数据上下文,但是每当进度更改时 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 对象,它工作得很好,但我希望我的“运行”方法来处理这个。这甚至可能吗?

4

3 回答 3

2

问题是您在调用 run 方法之前分配数据上下文,这意味着当您分配数据上下文“MyProgress”时,对象为“Null”..所以在调用“Run”方法之前数据上下文为 null..您正在调用为“MyProgress”创建实例的 Run 方法,但由于您的“MyClass”不是“INotifyPropertyChanged”,它无法通知数据上下文更改......

解决方案是:尝试在 MyClass 的构造函数中创建 MyProgress 实例。所以在分配数据上下文时不会为空,并且在 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.
  }
}
于 2012-10-09T09:16:51.840 回答
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>

// ...

于 2012-10-09T08:34:24.760 回答
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));
    }
}
于 2012-10-09T09:48:30.763 回答