我试图像here和here那样开发一个繁忙的窗口。我希望在我需要网格时可以看到网格,例如在我做长期任务的时候。
我现在做到了这一点:
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
答案 0 :(得分:2)
WPF已经有一个转换器,“booleanToVisibilityConverter”可以完成这项工作。
像这样编辑你的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}}