1

私はこれを見つけました:wpfデータバインディングが行われているときに読み込み中のグラフィック/アニメーションを表示する方法

しかし、それを私の仕事に適用する方法がわかりません。

メインウィンドウがあります。その中のすべてのユーザーコントロールを呼び出します。

ユーザーコントロールには、DataGridがあります。「実行」ボタンを押した後、データグリッドはMySQLからデータをロードします。時間がかかるので、データリグの読み込み中に「お待ちください」というダイアログウィンドウを表示したいと思います。

以下のリンクを見つけましたが、正しく呼び出す方法がわかりません。

この「ローダー」を「Loader.cs」のような新しいクラスファイルに入れて、ボタンで呼び出す必要がありますか?わかりましたが、データグリッドが終了したときにそれを閉じる方法は?

私は迷子になっています...他の解決策が存在し、単に使用する場合は...

よろしくお願いします

テストの編集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」などは表示されません...したがって、明日2番目のコードを試してみます。メソッドをどこに置いたかわかりません:(

編集2

私はあなたのコードで試しました...私は多分愚かすぎます。

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 = "";
    }
}
4

1 に答える 1

2

次のコードを、button-click-eventhandlerで呼び出されるDataGrid-UserControlのコードビハインドのメソッドに配置します。

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 };

今、あなたは決めることができます...

...データをロードし、完了時にDataLoadedイベントを発生させるDataLoaderクラスを作成する場合は、次を追加します。

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()Typeのデータを返し、TypeList<Donnees>がTypeの引数であるとしましょうint(すべてのTypeで機能します)。

データをロードする場所(たとえば、Window_Loaded-Event内)にこれを配置します。

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);

次に、コードビハインドでこのEventHandlerを呼び出します。

void loader_JobFinished(object sender, List<Donnees> result)
{
    YourDataGrid.DataSource = result
}
于 2012-10-18T12:37:18.853 に答える