poniedziałek, 31 stycznia 2011

ShowDialog() i Vista :)

Dawno nic tutaj nie wrzuciłem, aczkolwiek dzisiaj sam z siebie znalazł się ciekawy temat. Pisząc dodatek mający za zadanie import danych do XL ze wskazanego pliku natknąłem się na pewien problem. Coś normalnego dla XP:
 OpenFileDialog dialog = new OpenFileDialog();
 if (dialog.ShowDialog() == DialogResult.OK)
       {
        }

zawiesza XL w Viście. Okazało się, że OpenFileDialog korzysta z działającego już wątku - nie tworzy nowego, a co za tym idzie zawiesza moduł XL-a. Obejściem jest stworzenie osobnego wątku, który po wywołaniu otworzy nam nasze okno :) Przykład:
        private static DialogResult WywolajDialog(FileDialog dia)
        {
            DialogResult wynik = DialogResult.None;
            Thread t = new Thread(new ThreadStart(delegate
            {
                wynik = dia.ShowDialog();
            }));
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
            return wynik;
        } 

Następnie możemy już bez problemu wywołać nasze okno dialogowe:
OpenFileDialog dialog = new OpenFileDialog();
if (WywolajDialog(dialog) == DialogResult.OK)
                {
                }


Jak ktoś się pewnie zorientował po ApartmentState.STA, jeżeli mielibyśmy standardowy WindowsForm, a nie bibliotekę dla XL wystarczyłoby przed main() użyć [STAThread].