\

Školení Návrhové vzory, OOP a UML


 Tuesday, 09 June 2009
Chyba při používání prvku Popup v Silverlightu 2.0

Tento spot se objevil již před nějakou dobou jako komentář na Zdrojáku, ale protože se s podobným problémem setkal i Michal Kočí na Twitteru, dostal jsem pár emailů s popisem chyby v Silverlightu a znovu jsme narazili na podobné chyby při portaci firemního frameworku, dávám původní komentář i sem na na blog, abych měl kam trvale odkazovat další zoufalce. :)

Jestliže máte vlastni User Control, ve kterém je Popup a tento Popup neobsahuje ListBox (a možná další prvky), je možné Popup zobrazit a používat, aniž by byl přidán do kolekce Children rodičovské “stránky” (třída typicky nazvaná Page  – potomek UserControl) v Silverlightu. Takto definovaný POPUP funguje bez problémů.

<pexeso:popupbase x:class="RStein.Pexeso.SaveFile" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:pexeso="clr-namespace:RStein.Pexeso">

    <grid x:name="LayoutRoot" background="Black">

        <popup name="filesPopup">

            <popup.child>

                <stackpanel orientation="Vertical" background="Red">

                    <textblock text="Název souboru s uloženou hrou" fontsize="15" margin="5,5,5,0" horizontalalignment="Left" foreground="White" textdecorations="Underline"></textblock>

                    <stackpanel orientation="Horizontal">

                        <textbox name="txtFile" margin="5" minwidth="200"></textbox>

                        <textblock foreground="Yellow" visibility="Collapsed" name="txtError" text="Musíte zadat platný název souboru!" horizontalalignment="Left" verticalalignment="Center" fontweight="Bold" fontsize="10"></textblock>

                    </stackpanel>

                    <stackpanel orientation="Horizontal" margin="5">

                        <button style="{StaticResource DialogButton}" content="Uložit" name="btnSelect" click="btnSelect_Click"></button>

                        <button style="{StaticResource DialogButton}" content="Zpět" name="btnBack" click="btnCancel_Click"></button>

                    </stackpanel>

                </stackpanel>

            </popup.child>

        </popup>

    </grid>

</pexeso:popupbase>

 

Jestliže ale Popup obsahuje Listbox (a pravděpodobně i jiné prvky), Popup se zobrazí, ale při vybrání libovolné položky v ListBoxu celý Silverlight plugin spadne do obsluhy události UnhandledException a napíše jen něco o interní fatální chybě. Mimochodem, Bety a RC Silverlightu tímto problémem podle mě netrpěly.

Tento popup způsobí pád Silverlightu, jestliže popup není před svým zobrazením přidán do kolekce Children.

<pexeso:popupbase x:class="RStein.Pexeso.SelectFile" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:pexeso="clr-namespace:RStein.Pexeso">

    <grid x:name="LayoutRoot" background="Black">

        <popup name="filesPopup">

            <popup.child>

                <stackpanel orientation="Vertical" background="Red">

                    <textblock text="Vyberte uloženou hru" fontsize="15" margin="5,5,5,0" horizontalalignment="Left" foreground="White" textdecorations="Underline"></textblock>

                    <textblock foreground="Yellow" visibility="Collapsed" fontsize="10" name="txtError"></textblock>

                    <border cornerradius="20" background="White">

                        <listbox name="lstFiles" background="Orange" height="200">

                            <listbox.itemtemplate>

                                <datatemplate>

                                    <textblock text="{Binding Mode=OneWay}" foreground="White"></textblock>

                                </datatemplate>

                            </listbox.itemtemplate>

                        </listbox>

                    </border>

                    <stackpanel orientation="Horizontal">

                        <button style="{StaticResource DialogButton}" content="Vybrat soubor" name="btnSelect" click="btnSelect_Click"></button>

                        <button style="{StaticResource DialogButton}" content="Zpět" name="btnBack" click="btnCancel_Click"></button>

                    </stackpanel>

                </stackpanel>

            </popup.child>

        </popup>

    </grid>

</pexeso:popupbase>

 

Před zobrazením Popupu tedy musíme vždy přidat Popup do kolekce Children a po uzavřeni Popupu jej případně odebrat.


 

 private void btnLoad_Click(object sender, RoutedEventArgs e)

        {

            SelectFile file = new SelectFile();

            var files = FileAccessComponent.Instance.GetRootFiles();

            if (files.Length == 1)

            {

                return;

            }

 

            file.FileListBox.ItemsSource = files;           

 

            LayoutRoot.Children.Add(file); //Přidat do kolekce

 

            file.DialogClosed += file_DialogClosed; //Vlastní událost pro všechny mé dialogy

            showPopup(file.FilesPopup);

            file.FileListBox.Focus();

        }

 

        void file_DialogClosed(object sender, EventArgs e)

        {

            SelectFile sfDialog = sender as SelectFile;

 

            try

            {

                if (sfDialog.LastResult == DialogResult.OK && sfDialog.FileListBox.SelectedItem != null)

                {

                    m_currentGame = PexesoGame.Load(sfDialog.FileListBox.SelectedItem.ToString());

                    removeButtons();

                    rebindGameData();

                }

            }

            catch (Exception e1)

            {

                Console.WriteLine(e1);

            }

            finally

            {

                LayoutRoot.Children.Remove(sfDialog); //Odebrat z kolekce

                sfDialog.DialogClosed -= saveFileDialog_DialogClosed;

                hidePopup(sfDialog.FilesPopup);

            }

 

        }



Tuesday, 09 June 2009 09:51:20 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Silverlight