Diskuze: WPF - Binding Validation Exception Rule
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Tvůrce
Zobrazeno 38 zpráv z 38.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Věděl by někdo ? Nebo jsem zde jediný kdo využívá Data Binding ?
Já prostě mám zase extra chybu. Všude mají úplně stejné řešení a zdá se že to funguje, mě za boha ne
No,, a je správně vyhazovat výjimku v tomhle případě?
Já jsem si vždycky myslel, že výjimky se volej v případě, že to spadne
někam, kde by za normálního běhu se to vůbec nedostalo, což není ale
ověřování zadání textu...
(nikdy jsem ty výjimky podrobně nestudoval, takže se rád poučím)
Šlo by to třeba tak, že bys tam měl jinou property IsError a na tu bys bindoval přítomnost tooltipu s textem, barvu rámečku, atd..
Asi "zčásti" vyřešeno. Vypnul jsem ve VS při Debug modu v nastavení Exceptions - ArgumentException - odškrtnutí User-Unhandled. Ale to se mi jeví jako blbost největší, každopádně se to tváří jako funkční
Máš dvě chyby:
První problém se dá vyřešit:
Jinak ti nebude fungovat two-way binding.
Ta chyba, na kterou se ptáš, je kvůli null hodnotě:
INotifyPropertyChanged je potřeba pro TwoWay ? Mě funguje i bez něho. Jinak jej samozřejmě využívám .
Ono právě podle X různých tutoriálů popisují různé způsoby, jeden ze způsobů je vyhazování výjimky a ošetření přesně (nebo alespoň se mi to tak zdá) jak to mám já. Díky mrknu na to
Například zde: http://blog.magnusmontin.net/…tion-in-wpf/ + to samé mám v té knize. Výjimka se nezachytí a aplikace spadne. Když vypnu User-Handling vše funguje jak má
Omlouvám se za spam Nefunguje to ještě korektně. Ta validace je strašně pomalá a chvilku aplikace zamrzne
To, co ukazuje, je nejhorší způsob, jak to dělat. WPF podporuje binding na C# properties jen kvůli zpětné kompatibilitě. Takže ti to nikdy nebude fungovat "korektně", to je korektní chování. Používej radši DependencyProperty a vlastní ValidationRule
Vyzkoušel jsem si to v projektu a funguje to dobře.
Jako i pro klasicky DataBinding využívat DependencyProperty ? Doteď si vždy implmenetuju INotifyPropertyChanged, případně dále využívám Converter, DependencyProperty využívám u UserControls kde potřebuju nějaké vlastnosti bindovat
Ano, všude. WPF umí binding přes reflections a všude to ukazují, jak je to cool. Ale primární motivace pro tuhle featuru byla, abys mohl na WPF formuláře napojit už existující kód, kam nemůžeš dát DP.
Pokud píšeš nový kód, všude používej DependencyProperties. Jsou rychlé a umí toho mnohem víc - ale hlavně se chovají jako opravdové properties, umí dědit, vyvolat update/measure/arrange cyklus, atd.
Byl by jsi ochotný mi poslat ukázkový ViewModel kde implementuješ DependecyProperty apod ?
No co jsem pochopil MVVM, tak View binduje právě z ViewModel. Já nepotřebuju žádné opravdové zdrojové kódy Jen jestli by jsi nebyl (třeba časem) ochotný poslat nějaký příklad (učbenicový)
Ano, View binduje se na ViewModel, zatímco ViewModel nevidí o View. Jednoduše používej DP na ViewModelu i View a nepoužívej C# properties.
Mě osobně zatím přijde lepší využívat C# Properties. Jelikož definice DP
public static readonly DependencyProperty MyCustomProperty =
DependencyProperty.Register("MyCustom", typeof(string), typeof(Window1));
public string MyCustom
{
get
{
return this.GetValue(MyCustomProperty) as string;
}
set
{
this.SetValue(MyCustomProperty, value);
}
}
mě přijde strašně zdlouhavá a i obyčejná malá třída se 3 properties najednou nabobtná. Stále nevidím větší výhody, pokud tedy nepotřebuju validaci
Jinak ještě jedna věc. Já se zpočátku taky DP vyhýbal, protože mi přišly jako složitý mechanismus. Jenže pak jsem se koukal, jak jsou implementované a zjistil jsem, že jsou opravdu výhodnější.
No tak to jsi nepsal opravdovou aplikaci, která má tunu tříd Argument, že něco nabobtná funguje jen u projektů, které si napíšeš za hodinu. U větších aplikací to prostě nabobtná.
Jo a nepoužívej type-safe konverze, správně je to (string)GetValue(MyCustomProperty).
Kód jsem zkopíroval . A ne nebyla to aplikace na hodinu Nevidím v tom větší výhody (zatím). Binding kolekcí a properties mi funguje i přes klasické C# Property, propojím je tedy s ViewModelem. DP jsem využíval u vlastních Controls, kde jsem potřeboval aby nové vlastnosti Controlky šli Bindovat. Mrknu na to, díky Ale asi zůstanu ještě u klasických C# vlasntostí a implementací rozhraní
To, že jsi kód zkopíroval, ještě neznamená, že je správně
Já ho ani netestoval Chtěl jsem poukázat na to že oproti klasické C# Property která je na 2 řádky mám s DP několik řádků
No jo, jenže takhle to nemůžeš brát. To rovnou přestaň používat WPF a zůstaň u WinForms...
Celé WPF je optimalizované pro použití DependencyProperties, RoutedEvents a Commands. Stejně tak můžeš říct, že budeš používat eventy místo RoutedEvents a delegáty místo Commands.
V editoru stačí napsat propd a stisknout tab, zbytek už se dopíše sám (kromě metadat, která mají v šabloně špatně). Stejně tak to asi opisuješ z nějakých blogů, ale to jsou nespolehlivé zdroje informací, kdo myslíš, že je píše?
Když jsem vyvíjel obrovskou aplikaci pro WPF, ještě nebyly žádné blogy ani diskuze ani MVVM pattern. Jediný nástroj, který jsem měl, byl Reflector. Takže když něco nefungovalo, musel jsem kopat ve WPF. Také jsem reportoval asi 3 bugy do Microsoftu a nebyla sranda zjistit, jestli to mám špatně já nebo WPF.
Pionýrem slepých uliček byl Jára Cimrman, ale ty už si nemusíš procházet tím mortiriem, kterým si prošli ostatní, když bylo WPF v začátcích. Když dáš na moje rady, půjde ti to snáze a lépe. Když nedáš, tak nedáš, je to tvůj kód, ale až budeš psát další dotaz do diskuze, že něco nejde, vzpomeneš si na mě
Mám knihu od Charlese Petzolda - Mistroství ve WPF. Celkově mě i uráží, že si myslíš že to slepě využívám. Pravdou je že s XAML jsem se poprvé setkal u MODERN UI aplikací (Windows . DataBinding mi i lidé z Microsoftu v různých sample code ukazovali takto. Já na tvé rady dávám, ale stále v tom nevidím extra výhodu mít místo 2 řádků kódu, napsaných mnohem více.
Teď jsem si něco málo o DP přečetl z již zmíněné knihy. Je opravdu potřeba nastavovat všechny její metadata apod ? Vždyť než si nadefinuju i jednoduchý Model tak se upíšu. Přeci když potřebuji Binding (OneWay i TwoWay) implementuju INotifyPropertyChanged, přiřadím DataContext a svážu prvky s danými Properties, proč je při těchto požadavích lepší využít DP ?
Skvělé knihy jsou Essentials WPF a WPF Unleashed. A Petzold... kupoval jsem ji také. Jeho knihy jsou to nejpříšernější, co jsem kdy viděl, podle mě vyhozené peníze.
Výhodou používání DP je, že na nich celé WPF stojí. Začal jsi tohle vlákno, protože ti něco nefungovalo. To něco se dá napsat ve WPF asi pěti způsoby (jako skoro všechno ve WPF) a já ti odpověděl, že sis vybral nejhorší způsob, jak to napsat, protože je to tam kvůli zpětné kompatibilitě. Nejlepší způsob, jak to napsat, je používání DP, protože nebudeš muset psát další vlákna, co ti kde zase nefunguje. Je to dostatečně výhodné?
Pokud si myslíš, že se upíšeš, tak se těš, protože WPF je o upisování se. Než všechno nadefinuješ a propojíš, tak napíšeš tunu kódu ve srovnání s WinForms.
Dobrá ale stále jsem neslyšel nějak proč "je to nejhorší způsob". Opravdu nevidím důvod psát tunu kódu, jen kvůli tomu že chci Bindovat properties (nechci animace, nechci validaci,..), když mi postačí pár řádků a funguje to. DP se naučím a třeba uznám, že jsou výhodnější.
K samotnému problému. Jak jsem psal, už mi to funguje, jenom je ta validace nějaká pomalá cca 1-2 sec. jakoby aplikace zamrzne. Je to způsobené tedy to "nejhorší" možnou variantou a DP vše vyřeší (ačkoliv nechápu jak ) nebo je problém někde jinde ?
Díky za odpovědi, cením si jich A opravdu bych byl rád, kdyby jsi si našel chvíli a sepsal nějakou jednoduchou app, kde se bude bindovat a validovat jeden TextBox s použitím Dependency
Viz předchozí příspěvek: "nejhorší způsob, jak to napsat, protože je to tam kvůli zpětné kompatibilitě"
Zkoušel jsem si ráno ten tvůj příklad napsat za použití různých bindingů a validací a taky mi to "zamrzne", i když jen na desetinu sekundy. Když se podíváš do Output okna ve VS, uvidíš, že tam lítají výjimky z ConverterHelperu, myslím, že WPF se s tím neumí vyrovnat. Buď je problém interní výjimka v helperu nebo se tam hledá odpovídající šablona, což taky může trvat.
Když jsem místo toho použil vlastní ValidationRule, bylo to rychlé a bez zamrznutí. Takže řešení - vlastní ValidationRule místo explicitních výjimek.
Ještě jednou díky Musím se tedy pořádněji mrknout na ty DP a vlastně asi na spoustu dalších věcí.
Bývalý architekt WPF napsal knihu, mám ji doma také:
Ještě se tedy chci se zeptat. ExceptionValidationRule vůbec nepoužívat ? Přitom mi přijde, že když vyvolám výjimku a toto pravidlo (by jej mělo) zachytí je "lepší" (resp. z hlediska množství kódu menší) než psát vlastní ValidationRule. Pro dnešek asi poslední otázka
//EDIT
Už jsi mě asi i přesvědčil. Pokud to tak chápu, když třída dědí z
DependencyObject, stačí definovat DP a jednotlivé property. Jakákoliv změna
v code-behind se automaticky zpropaguje do View ? -> tedy, že
DependencyObject má něco jako INotifyPropertyChanged ?
Ano, nepoužívat, viz http://msdn.microsoft.com/…P.40%29.aspx#…
Data Validation and Error Reporting
However, throwing exceptions with properties in this way should be avoided where
possible. An alternative approach is to implement the IDataErrorInfo or
INotifyDataErrorInfo interfaces on your view model or model classes. These
interfaces allow your view model or model to perform data validation for one or
more property values and to return an error message to the view so that the user
can be notified of the error.
Koukám že appky ve Windows 8 mají předgenerované pomocné třídy a ty DP vůbec nepoužívají, tj implmentují klasicky INotifyPropertyChanged a klasické C# Properties
OK, také mám jeden dotaz. V čem je tenhle zápis kratší než DP?
public class Questionnaire : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string favoriteColor;
public string FavoriteColor
{
get { return this.favoriteColor; }
set
{
if (value != this.favoriteColor)
{
this.favoriteColor = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this,
new PropertyChangedEventArgs("FavoriteColor"));
}
}
}
}
}
Abstraktní třída
abstract class BindableClass : INotifyPropertyChanged
{
protected void Set(string property)
{
if(PropertyChanged !=null)
PropertyChanged(this,new PropertyChangedEventArgs(property))
}
public event PropertyChangedEventHandler PropertyChanged;
}
Třída (viewModel)
class TestClass : BindableClass
{
private int foo;
public int Foo { get { return foo; } set { foo = value; Set("Foo"); } }
}
Nechci nijak zpochybňovat tvá tvrzení, napsal jsi mi nové poznatky, které se rád doučím. Několik diskuzí ohledně DP vs INotifyPropertyChanged
http://stackoverflow.com/…pertychanged
http://stackoverflow.com/…in-viewmodel
Takže pokud nepotřebuju skrze XAML na tu vlastnost Bindovat (časté použití u vlastních controls, animace či styly) přijde mi lepší stále klasický přístup . Každopádně ještě určitě jednou díky, problém jak vyřešit jsi mi poradil a rozšířil jsi mi obzory
Čtu tu knížku o WPFku a tady se píše, že vše co dědí z DependencyObject bys měl využívat DP(když to teda využiješ). Vždyť se to generuje pomocí code snippetu (propdp) pak párkrát vytabuješ a máš to hned
Zobrazeno 38 zpráv z 38.