为什么我的繁忙页面不起作用?

时间:2014-06-20 09:20:19

标签: wpf xaml binding

我试图像herehere那样开发一个繁忙的窗口。我希望在我需要网格时可以看到网格,例如在我做长期任务的时候。

我现在做到了这一点:

XAML:

<Window x:Class="LoadingWindow2.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loadingWindow2="clr-namespace:LoadingWindow2"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <loadingWindow2:BoolToVisibilityConverter x:Key="boolConverter"/>
</Window.Resources>
<Grid>
    <Label HorizontalAlignment="Right">
        <Hyperlink Command="{Binding Path=DoSomething}">Do Something</Hyperlink>
    </Label>
    <Border BorderBrush="Black" BorderThickness="1" Background="#80000000" Visibility="{Binding IsBusy, Converter={StaticResource boolConverter}}" Grid.RowSpan="3">
        <Grid>
            <TextBlock Margin="0" TextWrapping="Wrap" Text="Please Wait..." HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" FontWeight="Bold" Foreground="#7EFFFFFF"/>
        </Grid>
    </Border>
</Grid>

我的.cs:

BusyViewModel.cs:

public class BusyViewModel : INotifyPropertyChanged
{
    private ICommand doSomethingCommand;

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsBusy { get; set; }

    public ICommand DoSomething
    {
        get { return doSomethingCommand ?? (doSomethingCommand = new DelegateCommand(LongRunningTask)); }
    }

    private void LongRunningTask()
    {
        var task = new Task(ComputeResults);
        task.Start();
    }

    private void ComputeResults()
    {
        this.IsBusy = true;
        Thread.Sleep(5000);
        this.IsBusy = false;
    }
}

DelegateCommand.cs:

public class DelegateCommand : ICommand
{
    private readonly Action executeMethod;
    private readonly Func<bool> canExecuteMethod;

    public DelegateCommand(Action executeMethod)
        : this(executeMethod, () => true)
    {
    }

    public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod)
    {
        if (executeMethod == null)
            throw new ArgumentNullException("executeMethod");
        if (canExecuteMethod == null)
            throw new ArgumentNullException("canExecuteMethod");

        this.executeMethod = executeMethod;
        this.canExecuteMethod = canExecuteMethod;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object stupid)
    {
        return CanExecute();
    }

    public bool CanExecute()
    {
        return canExecuteMethod();
    }

    public void Execute(object parameter)
    {
        Execute();
    }

    public void Execute()
    {
        executeMethod();
    }

    public void OnCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }
}

MainWindow.xaml.cs:

 public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new BusyViewModel();
    }

我从我复制的第一个链接下载了源代码,busy Grid正在显示。但在我的情况下......不是!我在这里做错了什么?

编辑:我按照建议删除了Converter。但它还没有工作......我添加了我的`MainWindow.xaml.cs&#34;

整个来源:here

1 个答案:

答案 0 :(得分:2)

WPF已经有一个转换器,“booleanToVisibilityConverter”可以完成这项工作。

请参阅http://msdn.microsoft.com/de-de/library/system.windows.controls.booleantovisibilityconverter%28v=vs.110%29.aspx

像这样编辑你的xaml:

<Window x:Class="LoadingWindow2.MainWindow"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:loadingWindow2="clr-namespace:LoadingWindow2"
   Title="MainWindow" Height="350" Width="525">
    <Window.Resources>    
        <BooleanToVisibilityConverter x:Key="boolConverter"/>
    </Window.Resources>
    <Grid x:Name="ROOT">
        <Label HorizontalAlignment="Right">
            <Hyperlink Command="{Binding Path=DoSomething}">Do Something</Hyperlink>
   </Label>
   <Border BorderBrush="Black" BorderThickness="1" Background="#80000000" Visibility="{Binding Path=IsBusy, Converter={StaticResource boolConverter}}" Grid.RowSpan="3">
       <Grid>
           <TextBlock Margin="0" TextWrapping="Wrap" Text="Please Wait..." 
            horizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" FontWeight="Bold" Foreground="#7EFFFFFF"/>
   </Border>
</Grid>

编辑: BusyViewMOdel的实施

public class BusyViewModel : INotifyPropertyChanged
{
private ICommand doSomethingCommand;

public event PropertyChangedEventHandler PropertyChanged;

private bool _isBusy = false;
public bool IsBusy 
{
    get { return _isBusy; }
    set
    {
       _isBusy = value;
       OnPropertyChanged("IsBusy");
    }
}

// Create the OnPropertyChanged method to raise the event
  protected void OnPropertyChanged(string name)
  {
      PropertyChangedEventHandler handler = PropertyChanged;
      if (handler != null)
      {
          handler(this, new PropertyChangedEventArgs(name));
      }
  }


public ICommand DoSomething
{
    get { return doSomethingCommand ?? (doSomethingCommand = new DelegateCommand(LongRunningTask)); }
}

private void LongRunningTask()
{
    var task = new Task(ComputeResults);
    task.Start();
}

private void ComputeResults()
{
    this.IsBusy = true;
    Thread.Sleep(5000);
    this.IsBusy = false;
}
}

请参阅http://msdn.microsoft.com/de-de/library/ms743695%28v=vs.110%29.aspx


编辑:尝试通过为网格指定名称而不是this.DataContext = ... public MainWindow() ... ROOT.DataContext = ...中的 private void LongRunningTask() { var task = new Task(ComputeResults); task.Start(); } private void ComputeResults() { this.IsBusy = true; // you did _isBusy = true. but to invoke OnPropertyChanged you need to use the setter, thus IsBusy! Works now even if set in the worker thread. Put it back to ComputeResults! Thread.Sleep(5000); this.IsBusy = false; } 来设置根网格上的数据上下文。查看更新的xaml!


编辑:搞定了。请参阅BusyViewModel类的此代码。

{{1}}