Диалозите трябва да се инициират от потребителя. с SaveFileDialog в Silverlight 3

Работя върху приложение Silverlight 3 с C#. Бих искал да позволя на потребителя да изтегли изображение от приложението Silverlight. Използвам SaveFileDialog, за да изпълня задачата за изтегляне на файл. Потокът върви по следния начин:

  1. Потребителят кликва върху бутона за изтегляне в приложението SL.
  2. Извиква се извикване на уеб услуга за получаване на изображението от сървъра
  3. OnCompleted асинхронен манипулатор на събития на извикването на уеб метода се извиква и получава двоичното изображение от сървъра
  4. В рамките на манипулатора на събитие OnCompleted SaveFileDialog подкани потребителя да запази изображението на компютъра.
  5. Поточно предаване на изображението към файла на твърдия диск на потребителя.

Използвам следния код във функция, която се извиква от манипулатора на събитие OnCompleted, за да изпълни подканата SaveFileDialog и след това стрийминг към файл.

            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "JPG Files|*.jpg" + "|All Files|*.*";
            bool? dialogResult = dialog.ShowDialog();

            if (dialogResult == true)
            {
                using (Stream fs = (Stream)dialog.OpenFile())
                {
                    fs.Write(e.Result, 0, e.Result.Length);
                    fs.Close();
                }
            }

SaveFileDialog ще изведе грешката „Диалоговите прозорци трябва да бъдат инициирани от потребителя“. когато извиквате метода ShowDialog в горния код. Какво може да ми липсва тук? Как да се преодолее това?


person pencilslate    schedule 30.08.2009    source източник


Отговори (5)


Това съобщение за грешка означава, че можете да показвате SaveFileDialog само в отговор на събитие, инициирано от потребителя, като например щракване върху бутон. В примера, който описвате, вие не показвате SaveFileDialog в отговор на кликване, а по-скоро в отговор на завършена http заявка (която не се счита за инициирано от потребителя събитие). И така, това, което трябва да направите, за да накарате това да работи, е в събитието Completed на http заявката да покажете някакъв потребителски интерфейс на потребителя, който казва „изтеглянето е завършено, щракнете тук, за да запазите файла на вашия компютър“, и когато потребителят щракне на това съобщение, покажете SaveFileDialog.

person KeithMahoney    schedule 31.08.2009
comment
Получих същото съобщение за грешка, опитвайки се да използвам SaveFileDialog директно от манипулатор на събитие Button_Click, защото правех известно валидиране в метода, преди да извикам new SaveFileDialog(). Връзката на JumpingJezza по-долу показва добър пример, но изглежда, че ключът е да имате new SaveFileDialog() като първи ред във вашия манипулатор на събития с бутони. След това привидно можете да правите каквото искате. - person Jedidja; 17.05.2011
comment
И първият ред наистина означава първи. Отстранявах грешки в кода на някой друг и един коментиран кодов блок в манипулатора на събития при щракване на бутон предизвика споменатото изключение. - person faester; 29.02.2012
comment
Мисля, че това е по-скоро проблем с времето, преди диалоговият прозорец за запазване да се отвори. Ако поставите точка на прекъсване преди dialog.ShowDialog() възниква грешка. Вижте dotnetslang. wordpress.com/2011/03/12/ - person maxence51; 28.06.2013

Какво ще кажете първо да попитате, преди да изтеглите? Изглежда, че от съобщението за грешка се предполага, че това е начинът, по който Silverlight иска да подканите, за да се увери, че знае, че даден потребител е поискал действието, а не вие ​​изпращате спам на потребителя с изскачащи прозорци.

Като оставим настрана модела за сигурност Silverlight, предпочитам да не чакам изтеглянето да приключи, преди да ме попитат къде да го поставя!

person Ray Hayes    schedule 31.08.2009

Както Кийт спомена, това е по проект. Този урок дава отличен пример за използване на код, който Преди изтеглях файл от сървъра по "правилния" начин. (Работи и в Silverlight 4)

person JumpingJezza    schedule 08.12.2010
comment
Можете също да създадете SaveFileDialog в манипулатора на събития на бутона. Ключът е да се уверите, че конструкторът е първият ред на метода. - person Jedidja; 17.05.2011

Току-що започнах със Silverlight 4 и имах същия проблем. Изглежда, че ако ръчно създадете манипулатори на събития, изключението за защита се хвърля, дори ако манипулаторът на събития обработва събитие с щракване на бутон с правилните параметри, но ако използвате опцията „създаване на нов манипулатор на събития“ на бутона в Xaml под събитието за щракване новият манипулатор на събития със същия код и параметри вече работи....това е едно от многото "тъпи" неща, на които се натъкнах от началото на прехода от WPF към Silverlight.

person Greg S    schedule 06.01.2011

person    schedule
comment
Бихте ли обяснили отговора си по-подробно? Отговорите трябва да предоставят насока, а не само c/p код. - person CodeMouse92; 23.10.2014