2012-10-18 83 views
1

我发现这一点:How to show a loading graphic/animation when wpf data binding is taking place加载动画在新窗口时WPF数据网格加载

但不知道如何运用它为我的工作。

我有我的主窗口。它会调用我所有的用户控件。

在用户控制,我有一个DataGrid。按“Go”按钮后,DataGrid会从MySQL加载数据。这需要很长时间,我想在加载数据生成过程中显示一个对话窗口,其中包含“Please Wait”。

我发现下面的链接,但不understant如何正确地调用它。

我需要把这个“装载”,在一个新的类文件,如“Loader.cs”以及所述按钮调用它呢?好吧,但如何在datagrid完成时关闭它?

我迷路了......那么,如果一个其他的解决办法存在,简单地使用...

由于通过提前

编辑测试1:

试过一个简单的测试与滑块以获得等待时间和一个按钮。

using System; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Controls; 

namespace TEST_LoadingPage 
{ 
/// <summary> 
/// Logique d'interaction pour MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnTester_Click(object sender, RoutedEventArgs e) 
    { 
     Window waitWindow = new Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None }; 
     waitWindow.Content = new TextBlock { Text = "Veuillez patienter...", FontSize = 30, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; 

     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += delegate 
     { 
      Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); })); 
      lbReussite.Visibility = Loop.Pause(slider.Value); 
      Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); })); 
     }; 
     worker.RunWorkerAsync(); 
    } 
} 

public class Loop 
{ 
    public static System.Windows.Visibility Pause(double duree) 
    { 
     try 
     { 
      DateTime begin = new DateTime(); 
      DateTime end = new DateTime(); 
      int i = 0; 
      begin = DateTime.Now; 
      end = DateTime.Now.AddSeconds(duree); 

      while (DateTime.Now <= end) 
       i++; 

      return System.Windows.Visibility.Visible; 
     } 
     catch (Exception) 
     { 
      return System.Windows.Visibility.Hidden; 
     } 
    } 
} 
} 

但不要错误的工作:

,因为不同的线程拥有它

调用线程不能访问该对象,我知道它柯朗错误,但我不“看不到‘DispatcherTimer’要不,我已经在先例项目见过......所以我会尽力的第二码明天BUT。我不明白的地方,我把我的方法:(

EDIT 2

我用你的代码试图......我太stupide说不定。

我已经写了类一个Loader.cs在我MainWiondow(其测试)

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnTester_Click(object sender, RoutedEventArgs e) 
    { 
     Loader<List<Donnees>> loader = new Loader<List<Donnees>>(GenerateList((int)slider.Value); 
     loader.JobFinished += new Loader<Donnees>.OnJobFinished(loader_JobFinished); 
     loader.Load(); 

    } 

    private List<Donnees> GenerateList(int number) 
    { 
     List<Donnees> list = new List<Donnees>(); 
     for (int i = 1; i <= number; i++) 
     { 
      Donnees data = new Donnees(); 
      data.Id = i; 
      data.Name = "Ligne " + i; 
      list.Add(data); 
     } 
     return list; 
    } 

    void loader_JobFinished(object sender, List<Donnees> result) 
    { 
     result = GenerateList((int)slider.Value); 
     dgDataGrid.ItemsSource = result; 
    } 

} 

public class Donnees 
{ 
    #region Properties 

    private int id; 
    public int Id 
    { 
     get { return id; } 
     set { id = value; } 
    } 

    private string name; 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    #endregion 

    public Donnees() 
    { 
     id = -1; 
     name = ""; 
    } 
} 
+0

是你能运用它为您的工作? –

+0

对不起,我在阻止其他问题,我还没有开始这项任务。我明天开始吧:)然后回到这里。 – Saesee

回答

2

你把下面的代码的方法,在你的DataGrid中,用户控件的代码隐藏它被调用在您的按钮,点击事件处理程序:

Window waitWindow = new Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None }; 
waitWindow.Content = new TextBlock { Text = "Please Wait", FontSize = 30, FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; 

现在你可以决定...

...如果你想创建的DataLoader类,它加载数据,并完成时触发一个事件DataLoaded,不是增加:

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += delegate 
{ 
    Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); })); 
    DataLoader dataLoader = new DataLoader(); 
    dataLoader.DataLoaded += delegate 
    { 
     Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); })); 
    }; 

    dataLoader.LoadData(); 
}; 

worker.RunWorkerAsync(); 

...或者如果你只是复制您的数据加载代码到这个方法并添加:

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += delegate 
{ 
    Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); })); 
    //do dataloading here 
    Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); })); 
}; 
worker.RunWorkerAsync(); 

编辑:我写了一个类,它应该做你想做的没有太多的代码,在代码隐藏:

public class Loader<TFuncResult,TFirstArgType>:FrameworkElement 
{ 
    private Func<TFirstArgType,TFuncResult> _execute; 
    public TFuncResult Result { get; private set; } 

    public delegate void OnJobFinished(object sender, TFuncResult result); 
    public event OnJobFinished JobFinished; 

    public Loader(Func<TFirstArgType,TFuncResult> execute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
    } 

    private Window GetWaitWindow() 
    { 
     Window waitWindow = new Window { Height = 100, Width = 200, WindowStartupLocation = WindowStartupLocation.CenterScreen, WindowStyle = WindowStyle.None }; 
     waitWindow.Content = new TextBlock { Text = "Please Wait", FontSize = 30, FontWeight = FontWeights.Bold, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; 

     return waitWindow; 
    } 

    public void Load(TFirstArgType firstarg, Window waitWindow = null) 
    { 
     if (waitWindow == null) 
     { 
      waitWindow = GetWaitWindow(); 
     } 
     BackgroundWorker worker = new BackgroundWorker(); 
     worker.DoWork += delegate 
     { 
      Dispatcher.BeginInvoke(new Action(delegate { waitWindow.ShowDialog(); })); 
      Result = _execute(firstarg); 
      Dispatcher.BeginInvoke(new Action(delegate() { waitWindow.Close(); })); 
     }; 
     worker.RunWorkerCompleted += delegate 
     { 
      worker.Dispose(); 
      if (JobFinished != null) 
      { 
       JobFinished(this, Result); 
      } 
     }; 
     worker.RunWorkerAsync(); 
    } 
} 

编辑2:如何使用它:

比方说你GenerateList()返回数据List<Donnees>类型和参数类型为int类型(包括所有类型的作品):

将此放在您想要加载数据的位置(例如在Window_Loaded - 事件):

Loader<List<Donnees>, int> loader = new Loader<List<Donnees>, int>(GenerateList); 
loader.JobFinished += new Loader<List<Donnees>, int>.OnJobFinished(loader_JobFinished); 
loader.Load((int)slider.Value); 

现在把这个事件处理程序的代码隐藏:

void loader_JobFinished(object sender, List<Donnees> result) 
{ 
    YourDataGrid.DataSource = result 
} 
+0

感谢您的快速回复。我将在我目前的工作之后测试这些代码,然后回顾我是否成功。 – Saesee

+0

我为你写了一个类,你可以使用它来加载数据,并在做这个时显示一个窗口。看我的编辑。 –

+0

我读过你的编辑但不明白如何使用它... 一个例子。我把这个类放在一个新的Class文件中? 我在我的DataGrid所在的UserControl中调用它? 如何调用它?那么我把MethodWhoLoadTheDataGrid()放在哪里? – Saesee