void AsyncToolTip_Loaded(object sender, RoutedEventArgs e)
        {
            GridCellData d = (GridCellData)DataContext;

            if (d == null)
            {
                return;
            }
            GetToolTipEventArgs args;

            if (!Strings.ContainsKey(d.RowData.Row))
            {
                args = new GetToolTipEventArgs(this, d);
                Strings.Add(d.RowData.Row, args);
                Text = DefaultToolTip;
            }
            args = Strings[d.RowData.Row];
            Text = args.CurrentToolTip;
            if (GetToolTip != null)
            {
                GetToolTip(this, args);
            }
            if (GetToolTipCommand != null && GetToolTipCommand.CanExecute(args))
            {
                GetToolTipCommand.Execute(args);
            }
        }
        void GetToolTip(object p)
        {
            GetToolTipEventArgs e = p as GetToolTipEventArgs;

            if (e.CurrentToolTip != e.DefaultToolTip)
            {
                return;
            }
            w         = new BackgroundWorker();
            w.DoWork += new DoWorkEventHandler(w_DoWork);
            w.RunWorkerAsync(e);
        }
        void w_DoWork(object sender, DoWorkEventArgs e)
        {
            i++;
            Thread.Sleep(TimeSpan.FromSeconds(1));
            GetToolTipEventArgs e1 = e.Argument as GetToolTipEventArgs;

            Dispatcher.BeginInvoke(new Action <GetToolTipEventArgs>((args) => {
                if (args == null || args.CellData == null || args.CellData.RowData == null)
                {
                    return;
                }
                string res1 = "ID: " + ((TestDataItem)args.CellData.RowData.Row).ID.ToString() + ", " + "Value: " + ((TestDataItem)args.CellData.RowData.Row).Value;
                args.SetToolTip(res1);
            }), new object[] { e1 }
                                   );
        }