Diskuze: Problém s WPF

C# .NET .NET (C# a Visual Basic) Problém s WPF American English version English version

Avatar
natech
Člen
Avatar
natech:

Dobrý den, začínám s WPF a narazil jsem na problém.
Mám panel s radioButtony.

<WrapPanel Grid.Column="2" Name="buttonPanel">
            <RadioButton Content="Žádná činnost" Name="radioButton1" IsChecked="True" Tag="0" Checked="radioButton1_Checked" />
            <RadioButton Content="Nová činnost" Name="radioButton2" Tag="1" Checked="radioButton1_Checked" />
        </WrapPanel>

Při funkci InitializeCom­ponent(); je vyvolána zpráva radioButton1_Chec­ked() a v tuto chvíli Tag je nastaven na NULL. Nechápu proč to je a nevím, jak to vyřešit (no poradit si dokážu, ale jak to vyřešit správně?
Díky za radu.

 
Odpovědět 16.3.2014 17:31
Avatar
Lako
Člen
Avatar
Odpovídá na natech
Lako:

Myslím si, že je to takle:
Když se zavolá initiallize component(), tak se vytvoří nová instance radiobuton, pak se začnou vyplňovat vlastnosti podle xamlu- checked se změní na true před tím, než se změní tag z null na 1, takže ta událost je volána dřív...
Musíš v tej metodě (radioButton1_Chec­ked) ověřit, jestli tag =! null..

 
Nahoru Odpovědět 16.3.2014 18:02
Avatar
Odpovídá na natech
Michal Žůrek (misaz):

Protože WPF musí jeden z těch dvou v incialize označit => to vyvolá prvotní událost.

Nahoru Odpovědět 16.3.2014 18:06
Nesnáším {}, proto se jim vyhýbám.
Avatar
natech
Člen
Avatar
Odpovídá na Michal Žůrek (misaz)
natech:

To sice máte oba pravdu, ale:
jako třetí na řádku je IsChecked="True" - tak se zaškrtne, ale zprávu neposílá
jako čtvrtý je na řádku Tag="0" - přiřadí TAG
jako pátý je Checked="radi­oButton1_Chec­ked" - až teď začne posílat zprávy.
Toto je chování, které bych očekával. Proč to tak není?

 
Nahoru Odpovědět 16.3.2014 22:40
Avatar
Odpovídá na natech
Michal Žůrek (misaz):

Ne, v XAMLu je jedno v jakém budou pořadí, posílá už první IsChecked="True". Řešením je si událost obsolužit až po inicialize v konstruktoru. Čili docílíš toho že nejprve se vše nastaví bez obsluhy a terpve po nastavení všeho si ji tam přidáš.

Nahoru Odpovědět 17.3.2014 6:32
Nesnáším {}, proto se jim vyhýbám.
Avatar
natech
Člen
Avatar
Odpovídá na Michal Žůrek (misaz)
natech:

Díky za odpověď. Myslel jsem, že v XAMLu je nějaký řád, ne že se to provádí v náhodném pořadí. Toto poslední řešení je to, co mě taky napadlo, ale nezdá se mi to úplně OK.

 
Nahoru Odpovědět 17.3.2014 17:20
Avatar
Odpovídá na natech
Michal Žůrek (misaz):

Tak druhá možnost je si předělat kód vygenerované metody inicializeCom­ponents.

Nahoru Odpovědět 17.3.2014 17:22
Nesnáším {}, proto se jim vyhýbám.
Avatar
coells
Redaktor
Avatar
Odpovídá na natech
coells:

V XAML na pořadí záleží i nezáleží. Bohužel, zrovna tady se jedná o chybný design XAML a narazil jsi na problém, který budeš muset obejít jinak.

Chyba spočívá v tom, že XAML je deklarativní programovací jazyk a jako takový by neměl řešit pořadí příkazů, pokud ho nelze explicitně vyjádřit. Podle XML specifikace u atributů nezáleží na pořadí, takže pořadí explicitně vyjádřit nejde. To by měl programátor respektovat. Ale je to těžké, když máš prvek, který se musí inicializovat v nějakém pořadí.

V praxi XAML zpracovává XML atributy zleva doprava, tedy v pořadí, jak jsi je napsal. Většinou se na to můžeš spolehnout, ale XAML se tím nemusí striktně držet. A zrovna v tomhle případě se toho nedrží, což je problém. Ještě dodám, že pořadí elementů už musí být respektováno, takže to XAML také respektuje.

Řešení se nabízejí následující:

  1. pokud ti nezáleží na prvním volání události, tak si do handleru dej kontrolu (Tag != null) a ignoruj chybné volání
  2. pokud ti záleží už na prvním volání, tak ze XAML odstraň IsChecked=true a přesuň to do metody OnInitialized() na nadřazeném UserControlu
  3. ve WPF bys neměl mít potřebu používat Tag, většinou se to dá nějak obejít, ať už kontrolou instance nebo přes attached properties, navíc při korektním použitím view-modelu by view nemělo obsahovat konceptuální ani modelová data, takže není důvod pro využití Tag
 
Nahoru Odpovědět 17.3.2014 22:56
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.