János's profileJános JankaPhotosBlogListsMore ![]() | Help |
|
February 27 Delphi Prism RoadmapÚj roadmap: itt. Ja, és ez legalább már nem kamu. Néhány érv mellette: Language Features
.NET Compatibility
Aspect Oriented Programming
Entity Framework support
Megjegyzés: February 26 WPF DataGrid sorszámokMutatok egy újabb kis trükköt, amit pont most találtam ki. Mivel a DataGrid nem képes megjeleníteni a sorszámot, ráadásul a DataGridRow csak egy GetIndex() metódust tartalmaz ennek lekérdezésére, szükség van egy property-re. Ugye a DataGridRowHeader, és a DataGridCell is, mint gyermekei jelennek meg a DataGridRow-nak. Ez jó, ezt ki lehet használni. A DataGrid-nek pedig van egy LoadingRow eseménye. Semmi más dolgunk nincs, mint készíteni egy attached property-t, ami kiegészíti a DataGridRow–ot egy index tulajdonsággal (ami a DataGridRow.GetIndex()-ből veszi az értékét): public sealed class DataGridRowExtender { public static int GetIndex(DataGridRow obj) { return (int)obj.GetValue(IndexProperty); } public static void SetIndex(DataGridRow obj, int value) { obj.SetValue(IndexProperty, value); } public static readonly DependencyProperty IndexProperty = DependencyProperty.RegisterAttached("Index", typeof(int), Csiszoltam valamennyit ehhez az UIHelper osztályon is: public sealed class UIHelper { public static T GetChildByType<T>(DependencyObject dpob) where T : DependencyObject { if (dpob == null) return null; var count = VisualTreeHelper.GetChildrenCount(dpob); for (var i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(dpob, i); T childAsT = child as T; if (childAsT != null) return childAsT; childAsT = GetChildByType<T>(child); if (childAsT != null) return childAsT; } return null; } public static T GetParentByType<T>(DependencyObject dpob) where T : DependencyObject { if (dpob == null) return null; var parent = dpob; while ((parent != null) && (parent is T == false)) parent = VisualTreeHelper.GetParent(parent); return parent as T; } } Ezt követően pedig megadjuk az attached property-t a DataGridRow-on, illetve bekötjük azt a DataGridRowHeader ControlTemplate-jében található vezérlőkbe: <!-- DataGridRow --> <Style TargetType="{x:Type basic:DataGridRow}"> <Setter Property="utils:DataGridRowExtender.Index" Value="-1"/> </Style> <!-- DataGridRowHeader --> <Style TargetType="{x:Type primitives:DataGridRowHeader}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="primitives:DataGridRowHeader"> <CheckBox VerticalAlignment="Center" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type basic:DataGridRow}}}" Content="{Binding Path=(utils:DataGridRowExtender.Index), Ha mindent jól csináltunk, az eredmény:
February 25 ExpressionDark.xamlLassan elkészül a saját Blend skinem. Azt kell tudni róla, hogy ez a létező téma könyvtáros változat lényeges feljavítása (illetve kijavítása), arról nem is beszélve, hogy ez a DataGrid-et is ráncba szedi. Tartalmaz alap validációs templatet is minden szükséges controlhoz, illetve néhány plusz vezérlő stílust is, mint pl. GroupBox, Grid, etc. Használat előtt szükség van a WPFToolkit-re is, amit innen lehet letölteni. A ExpressionDark téma Beta változata pedig innen letölthető. Használni pofonegyszerű: <Application x:Class="ThemeApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DispatcherUnhandledException="OnDispatcherUnhandledException" StartupUri="WinMain.xaml"> Remélem tetszik! Használjátok egészséggel! WPF Lambda converter extension & Converter LibraryMinden napra jut egy újdonság: Lambda Converter Extension February 24 WPF PasswordBox adatkötésHa egy PasswordBox-hoz szeretnénk kötni, szintén szükség van egy kis trükközésre, mivel a Microsoft biztonsági okokból nem dependency property-ként definiálta a PasswordBox password tulajdonságát: public static class PasswordBoxAssistant { public static readonly DependencyProperty BoundPassword = DependencyProperty.RegisterAttached("BoundPassword", WPF DataGrid stílizálásHa valaki szeretné egy kicsit kipofásítani a DataGrid-et (mint például én is), és netán gondjai támadnak egy-két elemmel, mint pl. a bal felső sarokban lévő Excel típusú Select All gomb, annak ajánlom figyelmébe ezt a kis cikket. A trükk egyébként mindössze annyi, hogy készítünk egy attached property-t a datagrid-hez, ami a vizuális fából előkukázott button template-jét lecseréli: public static class DataGridStyleBehaviour { public static ControlTemplate GetSelectAllButtonTemplate(DataGrid obj) { return (ControlTemplate)obj.GetValue(SelectAllButtonTemplateProperty); } public static void SetSelectAllButtonTemplate(DataGrid obj, ControlTemplate value) { obj.SetValue(SelectAllButtonTemplateProperty, value); } public static readonly DependencyProperty SelectAllButtonTemplateProperty = DependencyProperty.RegisterAttached("SelectAllButtonTemplate", typeof(ControlTemplate), typeof(DataGridStyleBehaviour), new UIPropertyMetadata(null, OnSelectAllButtonTemplateChanged)); private static void OnSelectAllButtonTemplateChanged( DependencyObject depObj, DependencyPropertyChangedEventArgs e) { var grid = depObj as DataGrid; if (grid == null) return; grid.Loaded -= OnGridLoaded; grid.Loaded += OnGridLoaded; } private static void OnGridLoaded(object sender, RoutedEventArgs e) { var grid = sender as DataGrid; if (grid == null) return; var bt = UIHelper.GetObjectOfTypeInVisualTree<Button>(grid); if (bt != null) bt.Template = GetSelectAllButtonTemplate(grid); } } Itt egy kis segédlet a kereséshez: public sealed class UIHelper { public static T GetObjectOfTypeInVisualTree<T>(DependencyObject dpob) where T : DependencyObject { int count = VisualTreeHelper.GetChildrenCount(dpob); for (int i = 0; i < count; i++) { DependencyObject child = VisualTreeHelper.GetChild(dpob, i); T childAsT = child as T; if (childAsT != null) return childAsT; childAsT = GetObjectOfTypeInVisualTree<T>(child); if (childAsT != null) return childAsT; } return null; } } Innen már gyerekjáték odatenni a stílusok közé: <ControlTemplate x:Key="SelectAllButtonTemplate" TargetType="{x:Type Button}"> <Grid> <Rectangle x:Name="Border" Fill="{StaticResource ExpressionPieDataPointBrush1}" SnapsToDevicePixels="True"/> <Polygon x:Name="Arrow" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="8,8,3,3" Opacity="0.15" Fill="{StaticResource TextBrush}" Stretch="Uniform" Points="0,10 10,10 10,0"/> </Grid> </ControlTemplate> <Style TargetType="basic:DataGrid"> <Setter Property="utils:DataGridStyleBehaviour.SelectAllButtonTemplate" February 23 C# INotifyPropertyChangedValaki aki ismeri a csapatot, légyszives mondja meg nekik, hogy az INotifyPropertyChanged automatikus implementálásához csináljanak valami kulcsszót. Folyamatosan azzal szívok, hogy elírom a dolgokat, pedig már így is egyszerűsítve van egy ObservableObject és egy generikus metódus segítségével az egész. Valami olyasmi kellene, mint a Delphi Prism-ben van: property Name: string; notify; Ez így sokkal szebb lenne C#-ban is, ráadásul nem írnám el a neveket, amik ráadásul olyan hibákhoz vezethetnek, hogy elég kinyomozni. Plusz gépelnem sem kellene annyit, mint a dög. Ezt légyszíves elolvasni: February 16 Silverlight kötési bugHa a usercontrol datacontextjét saját magához szeretnénk kötni, akkor egyszer csak azon találhatjuk magunkat, hogy kapunk egy szép nagy StackOverflowException-t. Ez már a Beta 2-ben is jelentkezett, de valami oknál fogva azóta se orvosolták (pedig be volt ígérve). Tehát, ez felejtős: public DataField() { InitializeComponent(); DataContext = this; // StackOverflowException } Workaround: public DataField() { InitializeComponent(); Binding binding = new Binding("DataPropertyName"); binding.Source = this; tbDataPropertyName.SetBinding(TextBlock.TextProperty, binding); } Amely esetben nem kapunk exception-t, viszont nem fog dolgozni, csak miután implementáljuk az INotifyPropertyChanged interfészt: public partial class DataField : UserControl, INotifyPropertyChanged { public DataField() { InitializeComponent(); Binding binding = new Binding("DataPropertyName"); binding.Source = this; tbDataPropertyName.SetBinding(TextBlock.TextProperty, binding); } public string DataPropertyName { get { return (string)GetValue(DataPropertyNameProperty); } set { SetValue(DataPropertyNameProperty, value); OnPropertyChanged("DataPropertyName"); } } public static readonly DependencyProperty DataPropertyNameProperty = DependencyProperty.Register("DataPropertyName", Ez egy nagyon szép bug, de szerencsére van megoldás. Sőt, van egy B megoldás is. Készítünk egy külön osztályt ami implementálja az INotifyPropertyChanged interfészt, majd azon megadjuk a tulajdonságokat és a UserControlon megadunk egy ilyen dependency property-t. A DataContext-et is frissíteni kell ilyenkor! Íme a példa: public class DataFieldProperties : ObservableObject { private string _dataPropertyName; public string DataPropertyName { get { return _dataPropertyName; } set { SetPropertyValue<string>( A UserControl dependency property-je: public DataFieldProperties DataFieldProperties { get { return (DataFieldProperties)GetValue(DataFieldPropertiesProperty); } set { SetValue(DataFieldPropertiesProperty, value); } } public static readonly DependencyProperty DataFieldPropertiesProperty = DependencyProperty.Register("DataFieldProperties", További jóhír, hogy a DataGrid frissítéséhez a DataContext-et null-ra kell állítani, majd vissza. Ezzel csak az a gond, hogy elugrik ilyenkor a kurzor az adott sorból és nem is lehet visszaállítani, mert a SelectedItem és SelectedIndex nem dolgoznak. Azt kitudom olvasni, hogy éppen melyik tételen állok, csak éppen visszaírni nem tudok bele semmit, mert nem reagál rá a grid. Mutatok valamit ebből, hogyan is nézne ez ki:
February 14 Silverlight 2.0Hát nem egy WPF. Azért ettől többet vártam volna. Kár volt 4 MB-ra összenyomni. Jobb lett volna, ha 10 MB, de normálisan implementálva lennének benne a WPF-ből a jó dolgok. Mik ezek? Egyrészt az adatkötés iszonyat gyenge a WPF-hez képest (szinte mindent kóddal kell leírjak, nincs RelativeSource se), másrészt pedig komoly hiányosságok vannak használhatóság terén, mint pl. ez itt: Helix (szerencsére így már van navigációs UI). De sorolhatnám ide a Silverlight Toolkit-et is (ami ad többek között editable comboboxot is, ami az én véleményem szerint kellene legyen alapból), na meg a nemrégiben kijavított DataGrid-et. Ez utóbbi különösen tetszett. Először azt hittem, hogy én szúrok el valamit, aztán ezt leszedve megvilágosodott, hogy az előző egy nagy bug halmaz volt. A command pattern rész sincs teljesen kidolgozva, úgyhogy még ilyen Composite WPF and Silverlight utángyártott dolgokra is szükség lesz. A másik csoda, amikor nem lehet kötni a user control dolgaihoz, sőt, ezt az RTM-be se javították ki: UserControl binding to own property bug in Sliverlight 2.0 RTM. Mondjuk ez az SLExtensions csomag elég ígéretesnek néz ki. Megmondom őszintén, én nem szeretem a netről ezeket összekukázni és úgy használni. Én a beépített, agyonratesztelt dolgokat szeretem. Ez a toldás, foldás nem az én műfajom. February 12 ADO.NET Data Services (Astoria) IIS7-beHa IIS-be szeretnénk hosztolni az ADO.NET Data Services (Astoria) szolgáltatásunkat, előtte néhány lépést mindenképpen szükséges megtenni a szerveren:
Pont most csinálok egy adatmanagement felületet ASP.NET + Astoria + Silverlight alapon. Egyenlőre most az ASP.NET Dynamic Data Entities Web Application nem játszik. Annyira nem komplikált a dolog, hogy szükség legyen rá, másrészt ez a projekt később át is alakul/alakulhat valami mássá a későbbiekben. Egyébként kellemes meglepetés, hogy milyen szépen lehet csacsogni a szerver oldali ASP.NET-es szolgáltatások és a Silverlight között: <services> Innentől kezdve már az autentikációs, profil, illetve szerepköri szolgáltatások elérhetőek a Silverlight kliensből is. Persze lehetne Silverlight-ból is autentikálni, erre van az AuthenticationService, de általában nem ez a bevett gyakorlat. Előbb jön a user, az ASP.NET-es oldalon belép, majd ha szükséges, akkor az SL kommunikál az őt körülvevő oldallal. Fantasztikus! Na most azért megjegyzem, nekem ezek teljesen új dolgok, 2 hete vágtam bele a webes témákba, de lenyűgöző. Már a HTML és CSS is kézre áll, a dízájn megoldásokkal sincs túl nagy probléma, nemsokára 1-2 héten belül mutatok valamit, hogy mire jutottam. ;) Saját EF projektGondoltam megosztok egy kis képet arról, hogy min is dolgozok, nehogy rám fogja valaki, hogy csak designt tervezek. Részletesebben nem tudok beszélni arról, hogy mi is ez egyenlőre (szakmai titok), de ez még csak a kezdet!
February 09 Csak parasztvakítás vagy tényleg szükséges?Úgy látom, hogy még mindig nehéz elfogadtatni néhány emberrel, hogy a design ugyanannyira fontos lehet, mint maguk a szolgáltatások, amit az adott termék nyújt. Persze erre mindenki rávágná rögtön, hogy “nézd a google puritán kereső oldalát!”. Van rajta két gomb, meg egy combobox, fehér alapon az egész, oszt csókolom, mégis az első számú kereső szolgáltatás. Pont most volt erről egy érdekes beszélgetésem a cég vezetőjével, aki szintén ez utóbbi elvet vallja. Nem tudom, hogy mikor fog ez a köztudatba beivódni, hogy emberek, ez a XXI. század! Ez már nemcsak kódolás, hanem egyfajta művészet is, aminek igen is, erős kifejezőereje van. Ez annyira igaz jelen esetben nálam, hogy hiába van google-nak ilyen, olyan, amolyan szolgáltatása, nem vagyok hajlandó használni. Persze ennek más okai is vannak, mint pl. a Live szoros integrálódása a többi MS szoftverrel, de esküszöm, a hangulatom is jobb, ha azt nézem, mint ezeket a puritán, unalmas, vagy fehér, vagy desktop esetén szürke alkalmazásokat. Cáfoljatok meg, de én spec. erősen vizuális típus vagyok, olyannyira, hogy számomra ez képes előtérbe kerülni a funkcionalitással szemben és nem is vagyok hajlandó olyan munkát kiadni a kezemből, ami nem felel meg korunk követelményeinek. Se most! Se később! February 08 Windows LiveMegjöttek az új Live programok. A Silverlight már ott virít benne: Kicsit soknak tűnik az a 144 MB, de van sávszél, töltsééé wazze! February 06 A nagy visszatérés Sziasztok! Hosszú kihagyások után újra itt vagyok. Véletlenül se higgyétek, hogy nem várnak meglepetések nálam (újra)! Mind WPF, sőt újabban ASP.NET, illetve még Delphi Win32 .NET objektumok fejlesztése terén is. WPF-hez közzéteszem nemsokára a saját XAML dictionary-s skin-eimet, minden alap WPF controlhoz. COOL! Aztán mutatok egy saját fejlesztésű JankaSoft Messenger-t, amit WPF és WCF házasítással készítettem egy igazi interaktív, designos felülettel (ez egyébként csak a skin tesztelése miatt készült). Ezt követően következnek az ASP.NET-be történő első élményeim, kezdve ott, hogy gyűlölöm a napot is, amikor kitalálták a HTML-t. A membership & role provájderek viszont a Világ egyik legnagyszerűbb találmányai. Elsőre szerintem alakul a dolog, és minden böngészőben jól jelenik meg az oldal is. Már DIV-ekkel álmodok. :) Ezt követően pedig közzéteszem a Delphi natív VCL-hez készült .NET-es generikus osztályaimat, interfészeimet, amik támogatják az attribútumok kezelését, teljes reflection könyvtár .NET mintára natív Win32-höz, illetve smart pointerek, automatikus memory management, ill. PFX, aszinkron programozás Win32-höz ... Jöjjön újra, aminek jönnie kell! |
|
|