Christian Moser's WPF Tutorial.net News and tutorials around the Windows Presentation Foundation en http://www.wpftutorial.net Sat, 04 Feb 2012 19:21:27 +0100 Home moc@zuehlke.com (Christian Moser) <table cellpadding="0" cellspacing="0"> <tr> <td style="width: 511px; padding-bottom: 20px; vertical-align: top;"> <h1>Welcome to the WPF Tutorial</h1> <img src="images/title.jpg" style="width: 400px; height: 349px; padding-left: 30px;" /> <p style="padding-top: 20px; padding-right: 10px; padding-left: 0px;">Welcome to my website about the Windows Presentation Foundation. The tutorials will show you how to create the next generation user experience. I hope you will get amazed by the possibilities of this fascinating technology.</p> <br/> [news] </td> <td rowspan="2" style="padding-left: 30px; margin-top: 10px; vertical-align: top; border-left: #eeeeee 1px solid;" > [tipofday] [popular] </td> </tr> </table> http://www.wpftutorial.net/Home.html Sat, 04 Feb 2012 19:21:27 +01002012-01-25 13:18:20 List of 3rd-Party Controls moc@zuehlke.com (Christian Moser) <h1>WPF - Third Party Controls</h1> <h2>WPF Component Vendors</h2> <ul> <li><a href="http://www.mindscapehq.com/products/wpfelements">Mindscape</a></li> <li><a href="http://www.componentart.com/products/wpf/navigation/">Component Art</a></li> <li><a href="http://www.devexpress.com/Products/NET/Controls/WPF/">DevExpress</a></li> <li><a href="http://www.syncfusion.com/products/user-interface-edition/wpf">SyncFusion</a></li> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf.aspx#Overview">Infragistics</a></li> <li><a href="http://xceed.com/pages/TopMenu/Products/ProductSearch.aspx?Lang=EN-CA&Category=0617b4dd-af9a-4e34-a1a1-d1129237d614">Xceed</a></li> <li><a href="http://www.telerik.com/products/wpf.aspx">Telerik</a></li> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/WPFStudio/Default.aspx">Actipro</a></li> <li><a href="http://www.divil.co.uk/net/controls/wpf.aspx">divelements</a></li> <li><a href="http://www.binarymission.co.uk/">Binary Mission</a></li> </ul> <hr> <table> <tr> <td style="vertical-align: top; width: 300px;"> <h2>Bar Code</h2> <ul> <li><a href="http://www.neodynamic.com/Products/Barcode-WPF/Barcode_wpf_Feature_Details.aspx">Neodynamics BarCode</a></li> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/BarCode/Default.aspx">Actipro BarCode</a></li> </ul> <h2>Data Grids</h2> <ul> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamdatagrid.aspx#Overview">Infragistics Data Grid</a></li> <li><a href="http://xceed.com/Grid_WPF_New.html">Xceed Data Grid</a></li> <li><a href="http://www.componentone.com/SuperProducts/GridWPF/ ">Component One Data Grid</a></li> <li><a href="http://www.syncfusion.com/products/user-interface-edition/wpf/grid">Syncfusion Essential Grid</a></li> <li><a href="http://www.telerik.com/products/wpf/gridview.aspx">Telerik RadGridView for WPF</a></li> <li><a href="http://www.componentart.com/products/wpf/datagrid/">ComponentArt DataGrid</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/data-grid">Mindscape Datagrid</a></li> </ul> <h2>Charts</h2> <ul> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamchart.aspx#Overview ">Infragistics xamChart</a></li> <li><a href="http://sourceforge.net/projects/swordfishcharts">Swordfish Charts</a></li> <li><a href="http://www.componentone.com/SuperProducts/ChartWPF/ ">Component One Chart</a></li> <li><a href="http://www.visifire.com/">Visifire Chart for WPF and Silverlight</a></li> <li><a href="http://www.codeproject.com/KB/WPF/wpfgraph.aspx">WPF Graph on Code Project</a></li> <li><a href="http://www.codeproject.com/KB/WPF/WPF_3D_Bar_chart_control.aspx">Free 3D Chart</a></li> <li><a href="http://www.codeproject.com/KB/WPF/WPFChart3D.aspx">Free High Performance 3D Chart</a></li> <li><a href="http://dynamicdatadisplay.codeplex.com/">D3 Dynamic Data Display</a></li> <li><a href="http://www.syncfusion.com/products/user-interface-edition/wpf/chart">Syncfusion Essential Chart</a></li> <li><a href="http://www.syncfusion.com/products/user-interface-edition/wpf/gauge">Syncfusion Gauge</a></li> <li><a href="http://www.telerik.com/products/wpf/gauge.aspx">Telerik RadGauge for WPF</a></li> <li><a href="http://www.telerik.com/products/wpf/chart.aspx">Telerik RadChart for WPF</a></li> <li><a href="http://www.componentart.com/products/wpf/charting/">ComponentArt Chart</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-bar-chart">Mindscape Chart</a></li> <li><a href="http://www.softwarefx.com/sfxNetProducts/ChartFX/wpf/">ChartFX for WPF</a></li> <li><a href="http://www.nextwavesoft.com/products/nextwave-chart-for-wpf">NextWave Chart for WPF</a></li> <li><a href="http://www.nextwavesoft.com/products/nextwave-gauge-for-wpf">NextWave Gauge for WPF</a></li> </ul> <h2>Color Picker</h2> <ul> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-color-picker">Mindscape Color Picker</a></li> <li><a href="http://www.telerik.com/products/wpf/colorpicker.aspx">Telerik Color Picker</a></li> <li><a href="http://wpfcolorpicker.codeplex.com/">Free Color Picker (CodePlex)</a></li> <li><a href="http://www.componentone.com/SuperProducts/ColorPickerWPF/">Component One Color Picker</a></li> </ul> <h2>Diagram Editors</h2> <ul> <li><a href="http://visualizationtools.net/default/productsoverview/">Orbifold Visualizers</a></li> <li><a href="http://www.syncfusion.com/products/user-interface-edition/wpf/diagram">Syncfusion Essential Diagram Editor</a></li> </ul> <h2>Dialogs and Windows</h2> <ul> <li><a href="http://wpfdialogs.codeplex.com/">Pure WPF FileOpen, FileSave and FolderBrowser Dialogs</a></li> <li><a href="http://www.divil.co.uk/net/controls/sandshellwpf/">divelements Shell</a></li> </ul> <h2>Dock</h2> <ul> <li><a <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamdockmanager.aspx#Overview ">Infragistics Dock Manager</a></li> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/Docking/Default.aspx">Actipro Dock Panel</a></li> <li><a href="http://www.devcomponents.com/dotnetbar-wpf/">DevComponents Dock Panel</a></li> <li><a href="http://sourceforge.net/projects/wpfdockinglib/">WPF Docking Library (Open Source)</a></li> <li><a href="http://avalondock.codeplex.com">Avalon Dock (Open Source)</a></li> <li><a href="http://www.telerik.com/products/wpf/docking.aspx">Telerik RadDocking for WPF</a></li> <li><a href="http://www.divil.co.uk/net/controls/sanddockwpf/screenshots.aspx">divelements Dock</a></li> </ul> <h2>Editors</h2> <ul> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xameditors.aspx#Overview ">Infragistics xamEditors</a></li> <li><a href="http://xceed.com/Editors_WPF_Intro.html">Xceed Editors</a></li> <li><a href="http://www.devcomponents.com/dotnetbar-wpf/WPFNumericDoubleInput.aspx ">DevComponents Numeric Editor</a></li> <li><a href="http://www.telerik.com/products/wpf/numericupdown.aspx">Telerik RadNumericUpDown for WPF</a></li> <li><a href="http://www.syncfusion.com/products/user-interface-edition/wpf/edit">Syncfusion Essential Edit (with Syntax Highlighting)</a></li> <li><a href="http://wpfcalendarcontrol.codeplex.com/">WPF Calendar Control</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-rich-text-toolbar">Mindscape Rich Text Editor</a></li> <li><a href="http://www.telerik.com/products/wpf/image-editor.aspx">Telerik Image Editor</a></li> </ul> <h2>Effects</h2> <ul> <li><a href="http://www.codeplex.com/transitionals">Transitionals - Framework to transition between screens.</li> <li><a href="http://www.codeplex.com/fx">WPF Shader and Transition FX</a></li> <li><a href="http://www.codeplex.com/wpffx">Windows Presentation Foundation Pixel Shader Effects Library</a></li> <li><a href="http://www.codeplex.com/dotwaywpf">DotWay WPF - Color Picker, Panels and several Shader Effects</a></li> <li><a href="http://www.telerik.com/products/wpf/drag-drop.aspx">Telerik Drag&amp;Drop for WPF</a></li> </ul> <h2>GIS and Maps</h2> <ul> <li><a href="http://resources.arcgis.com/content/arcgis-api-silverlightwpf/1.2/about">ESRI ArcGIS Controls for WPF</a></li> <li><a href="http://vewpf.codeplex.com/">Microsoft Virual Earth Control</a></li> <li><a href="http://wpfsharpmapcontrols.codeplex.com/">Sharp Map Control</a></li> </ul> <h2>Multimedia</h2> <ul> <li><a href="http://directshownet.sourceforge.net/">DirectShowLib - .NET Wrapper for DirectShow</a></li> <li><a href="http://videorendererelement.codeplex.com/">VideoRenderElement</a></li> <li><a href="http://wpfcap.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=13380#ReleaseFiles">Webcam Control</a></li> <li><a href="http://www.codeplex.com/WPFMediaKit">WPF Media Kit - DVD Player, DirectShow, WebCam</li> </ul> </td> <td style="padding-left: 40px; vertical-align: top;"> <h2>Misc</h2> <ul> <li><a href="http://www.codeplex.com/wpf/Release/ProjectReleases.aspx?ReleaseId=15598">WPF Toolkit</a></li> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamTabControl.aspx#Overview ">Infragistics Tab Control</a></li> <li><a href="http://www.mindscape.co.nz/products/wpfflowdiagrams/">Mindscape Flow Diagrams</a></li> </ul> <h2>Outlook Bar</h2> <ul> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamOutlookBar.aspx#Overview ">Infragistics Outlook Bar</a></li> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/Navigation/Default.aspx">Actipro Outlook Bar</a></li> <li><a href="http://www.devcomponents.com/dotnetbar-wpf/NavigationPane.aspx">DevComponents Outlook Bar</a></li> <li><a href="http://www.codeproject.com/KB/WPF/WPFOutlookBar.aspx">Odyssey Outlook Bar</a></li> <li><a href="http://www.codeproject.com/KB/WPF/WPFExplorerBar.aspx">Odyssey Explorer Bar</a></li> <li><a href="http://www.telerik.com/products/wpf/outlookbar.aspx">Telerik RadOutlookBar for WPF</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-outlook-bar">Mindscape Outlook Bar</a></li> <li><a href="http://www.componentone.com/SuperProducts/OutlookBarWPF/">Component One Outlook Bar</a></li> </ul> <h2>Panels</h2> <ul> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamcarouselpanel.aspx#Overview">Infragistics Carousel Panel</a></li> <li><a href="http://www.telerik.com/products/wpf/carousel.aspx">Telerik WPF Carousel Control</a></li> <li><a href="http://www.telerik.com/products/wpf/tileview.aspx">Telerik RadTileView for WPF</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-coverflow-control">Mindscape Coverflow Control</a></li> <li><a href="http://www.telerik.com/products/wpf/virtualizingwrappanel.aspx">Telerik Virtualizing Wrap Panel</a></li> <li><a href="http://www.componentone.com/SuperProducts/HyperPanelWPF/">Component One HyperPanel</a></li> </ul> <h2>Progress Bars</h2> <ul> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-progress-bar">Mindscape Progress Bar</a></li> </ul> <h2>Property Grids</h2> <ul> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/PropertyGrid/Default.aspx">Actipro Property Grid</a></li> <li><a href="http://www.mindscape.co.nz/products/WpfPropertyGrid/default.aspx">Mindscape Property Grid</a></li> <li><a href="http://www.componentone.com/SuperProducts/PropertyGridWPF/">Component One Property Grid</a></li> </ul> <h2>Reporting</h2> <ul> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/reporting.aspx#Overview ">Infragistics Reporting for WPF</a></li> <li><a href="http://www.componentone.com/SuperProducts/ReportsWPF/">Component One Reports</a></li> <li><a href="http://www.componentone.com/SuperProducts/PdfViewerWPF/">Component One PDF Viewer</a></li> </ul> <h2>Ribbon</h2> <ul> <li><a href="http://fluent.codeplex.com">Fluent Ribbon Control Suite</a></li> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamRibbon.aspx#Overview">Infragistics Ribbon</a></li> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/Ribbon/Default.aspx">Actipro Ribbon</a></li> <li><a href="http://www.devcomponents.com/dotnetbar-wpf/wpfribbon/ ">DevComponents Ribbon</a></li> <li><a href="http://www.codeproject.com/KB/WPF/OdysseyRibbonBar.aspx">Odyssey Ribbon</a></li> <li><a href="http://www.telerik.com/products/wpf/ribbonbar.aspx">Telerik WPF UI RibbonBar</a></li> <li><a href="http://windowsclient.net/wpf/wpf35/wpf-35sp1-ribbon-walkthrough.aspx">Free Microsoft WPF Ribbon Control</a></li> <li><a href="http://www.divil.co.uk/net/controls/sandribbonwpf/">divelements Ribbon</li></a> <li><a href="http://www.binarymission.co.uk/Products/wpf/ribbon-wpf.html">BinaryMisson Ribbon</a></li> </ul> <h2>Schedule</h2> <ul> <li><a href="http://www.devcomponents.com/dotnetbar-wpf/WPFScheduleControl.aspx ">DevComponents Schedule Control</a></li> <li><a href="http://www.devcomponents.com/dotnetbar-wpf/WPFDateTimePicker.aspx ">DevComponents DateTime Picker</a></li> <li><a href="http://www.componentone.com/SuperProducts/SchedulerWPF/">Component One Schedule</a></li> <li><a href="http://timeline.codeplex.com/">Timeline Control</a></li> <li><a href="http://www.telerik.com/products/wpf/scheduler.aspx">Telerik RadScheduler for WPF</a></li> <li><a href="http://wpfschedule.codeplex.com/">Free WPF Schedule Control</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-scheduler">Mindscape Schedule Control</a></li> <li><w href="http://www.mindscapehq.com/products/wpfelements/controls/time-explorer">Mindscape Time Explorer</a></li> <li><a href="http://www.infragistics.com/dotnet/netadvantage/wpf/xamMonthCalendar.aspx#Overview">Infragistics MonthCalendar</a></li> </ul> <h2>Slider</h2> <ul> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-dual-slider">Mindscape Dual-Slider</a></li> <li><a href="http://www.componentone.com/SuperProducts/RangeSliderWPF/">Component One Dual-Slider</a></li> </ul> <h2>Toolbar</h2> <ul> <li><a href="http://www.devexpress.com/Products/NET/Controls/WPF/Bar_Menu/">DevExpress ToolBar</a></li> <li><a href="http://www.codeproject.com/KB/tree/WPFBreadcrumbBar.aspx">Odyssey Breadcrumb Bar</a></li> <li><a href="http://www.componentart.com/products/wpf/navigation/">ComponentArt Toolbar</a></li> </ul> <h2>Theming</h2> <ul> <li><a href="http://wpfthemeselector.codeplex.com/">WPF Theme Selector</a></li> </ul> <h2>Tree</h2> <ul> <li><a href="http://www.telerik.com/products/wpf/treeview.aspx">Telerik RadTree View for WPF</a></li> <li><a href="http://www.mindscapehq.com/products/wpfelements/controls/wpf-multicolumn-tree-view">Mindscape Multicolumn Tree</a></li> </ul> <h2>Web Browser</h2> <ul> <li><a href="http://wpfchromium.codeplex.com/SourceControl/changeset/view/28084#413984">Chromium Web Browser</a></li> </ul> <h2>Wizard</h2> <ul> <li><a href="http://www.divil.co.uk/net/controls/wizardframeworkwpf/">divelements Wizard</a></li> <li><a href="http://www.actiprosoftware.com/Products/DotNet/WPF/Wizard/Default.aspx">Actipro Wizard</a></li> </ul> <h2>3D</h2> <ul> <li><a href="http://xceed.com/3DViews_WPF_Intro.html">Xceed 3D Views</a></li> </ul> </td> </tr> </table> http://www.wpftutorial.net/3rdPartyLibs.html Sat, 04 Feb 2012 19:21:27 +01002012-01-08 11:50:58 Undo/Redo moc@zuehlke.com (Christian Moser) <h1>How to implement undo/redo using MVVM</h1> <h3>Introduction</h3> <p>One feature that many users demand is a neatless undo/redo integration. This means that the application allows the user to revert any modification he made - one by one - back to the start of the application and than eventually reapply them again. This improves the usability a lot, because it allows the user to carelessly use an unclear command, because he is certain, that he can undo it if he was wrong. Today undo/redo has gotten almost standard for any modern data editing application.</p> <img style="padding-left: 150px;" src="images/undoredo.png" /> <h3>The MVVM-Pattern</h3> <p>Because of the strong databinding functionality in WPF, most applications are using the popular MVVM (Model-View-ViewModel) pattern. The idea of this pattern is basically to define a class that aggregates all data and commands for a certain view and provides them to the view as properties where it can bind to. Changes on properties are notified by an event on the <code>INotifyPropertyChanged</code> interface.</p> <h3>A concept of implementing undo/redo</h3> <p>A classical approach to implement undo/redo is to allow changes on the model only through commands. And every command should be invertible. The user than executes an action, the application creates a command, executes it and puts an inverted command on the undo-stack. When the user clicks on undo, the application executes the top-most (inverse) command on the undo-stack, inverts it again (to get the original command again) and puts it on the redo-stack. That's it.</p> <p><b>Scenario 1: Executing an action</b></p> <img style="padding-left: 50px;" src="images/undoredo1.png" /> <p><b>Scenario 2: Undoing an action</b></p> <img style="padding-left: 50px;" src="images/undoredo2.png" /> <h3>Adoption for WPF</h3> <p>We start with a base class that implements the <code>INotifyPropertyChanged</code> interface and provides a private method <code>Notify(string propertyName)</code>. <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">class</span> NotifyableObject <span style="color: #008000;">:</span> INotifyPropertyChanged <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">event</span> PropertyChangedEventHandler PropertyChanged; <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">void</span> Notify<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">string</span> propertyName<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span>PropertyChanged <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> PropertyChanged<span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> PropertyChangedEventArgs<span style="color: #000000;">&#40;</span>propertyName<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> <p>Then we build the base class <code>TrackableObject</code> where all model objects or view models that are directly bound to the view should inherit from. <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">class</span> TrackableObject <span style="color: #008000;">:</span> NotifyableObject <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> List<span style="color: #008000;">&lt;</span>ITrackable<span style="color: #008000;">&gt;</span> _trackableItems <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> List<span style="color: #008000;">&lt;</span>ITrackable<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">bool</span> HasChanges <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _trackableItems.<span style="color: #0000FF;">Any</span><span style="color: #000000;">&#40;</span>i <span style="color: #008000;">=&gt;</span> i.<span style="color: #0000FF;">HasChanges</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> IModificationTracker ModificationTracker <span style="color: #000000;">&#123;</span> get; set; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">protected</span> TrackableValue<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> RegisterTrackableValue<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">string</span> propertyName, T defaultValue <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">default</span><span style="color: #000000;">&#40;</span>T<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var property <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> TrackableValue<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>propertyName, Modify, Notify, defaultValue<span style="color: #000000;">&#41;</span>; _trackableItems.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>property<span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">return</span> property; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">protected</span> TrackableCollection<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> RegisterTrackableCollection<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var collection <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> TrackableCollection<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>Modify<span style="color: #000000;">&#41;</span>; _trackableItems.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>collection<span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">return</span> collection; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> Modify<span style="color: #000000;">&#40;</span>Action doAction, Action undoAction, Action notification<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var modification <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> Modification<span style="color: #000000;">&#40;</span>doAction, undoAction, notification<span style="color: #000000;">&#41;</span>; modification.<span style="color: #0000FF;">Execute</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; ModificationTracker.<span style="color: #0000FF;">TrackModification</span><span style="color: #000000;">&#40;</span>modification<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> <p>To simplify the generation of modifactions when changing a property value, we build a generic wrapper for each property called <code>TrackableValue</code>. <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">class</span> TrackableValue<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #008000;">:</span> ITrackable <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> <span style="color: #2b91af; font-weight: bold;">string</span> _propertyName; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> Action<span style="color: #008000;">&lt;</span>Action, Action, Action<span style="color: #008000;">&gt;</span> _modifyCallback; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> Action<span style="color: #008000;">&lt;</span><span style="color: #2b91af; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span> _notifyAction; <span style="color: #0600FF; font-weight: bold;">private</span> T _value; <span style="color: #0600FF; font-weight: bold;">public</span> TrackableValue<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">string</span> propertyName, Action<span style="color: #008000;">&lt;</span>Action, Action, Action<span style="color: #008000;">&gt;</span> modifyCallback, Action<span style="color: #008000;">&lt;</span><span style="color: #2b91af; font-weight: bold;">string</span><span style="color: #008000;">&gt;</span> notifyAction, T defaultValue<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> _propertyName <span style="color: #008000;">=</span> propertyName; _modifyCallback <span style="color: #008000;">=</span> modifyCallback; _notifyAction <span style="color: #008000;">=</span> notifyAction; _value <span style="color: #008000;">=</span> defaultValue; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">bool</span> HasChanges <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _originalValue.<span style="color: #0000FF;">Equals</span><span style="color: #000000;">&#40;</span>_value<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> T Value <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _value; <span style="color: #000000;">&#125;</span> set <span style="color: #000000;">&#123;</span> var oldValue <span style="color: #008000;">=</span> _value; _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> _value <span style="color: #008000;">=</span> value, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> _value <span style="color: #008000;">=</span> oldValue, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> _notifyAction<span style="color: #000000;">&#40;</span>_propertyName<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> <p>To same thing we need to do for collections to track add/remove of items from a collection</p> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">class</span> TrackableCollection<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> <span style="color: #008000;">:</span> IList<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span>, ITrackable <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> Action<span style="color: #008000;">&lt;</span>Action, Action, Action<span style="color: #008000;">&gt;</span> _modifyCallback; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> List<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> _list <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> List<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> List<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> _originalList <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> List<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">public</span> TrackableCollection<span style="color: #000000;">&#40;</span>Action<span style="color: #008000;">&lt;</span>Action, Action, Action<span style="color: #008000;">&gt;</span> modifyCallback<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> _modifyCallback <span style="color: #008000;">=</span> modifyCallback; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">event</span> EventHandler<span style="color: #008000;">&lt;</span>EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;&gt;</span> ItemAdded; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">event</span> EventHandler<span style="color: #008000;">&lt;</span>EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;&gt;</span> ItemRemoved; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">event</span> EventHandler CollectionChanged; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">bool</span> HasChanges <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span> _list.<span style="color: #0000FF;">Count</span> <span style="color: #008000;">==</span> _originalList.<span style="color: #0000FF;">Count</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _list.<span style="color: #0000FF;">Where</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>item, index<span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #008000;">!</span>item.<span style="color: #0000FF;">Equals</span><span style="color: #000000;">&#40;</span>_originalList<span style="color: #000000;">&#91;</span>index<span style="color: #000000;">&#93;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Any</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">return</span> true; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">void</span> AcceptChanges<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> _originalList.<span style="color: #0000FF;">Clear</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; _originalList.<span style="color: #0000FF;">AddRange</span><span style="color: #000000;">&#40;</span>_list<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> IEnumerator<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span> GetEnumerator<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _list.<span style="color: #0000FF;">GetEnumerator</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> IEnumerator IEnumerable.<span style="color: #0000FF;">GetEnumerator</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> GetEnumerator<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">void</span> Add<span style="color: #000000;">&#40;</span>T item<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; ItemAdded.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Remove</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; ItemRemoved.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, OnCollectionModified<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">void</span> Clear<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var items <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> T<span style="color: #000000;">&#91;</span>_list.<span style="color: #0000FF;">Count</span><span style="color: #000000;">&#93;</span>; _list.<span style="color: #0000FF;">CopyTo</span><span style="color: #000000;">&#40;</span>items<span style="color: #000000;">&#41;</span>; _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0600FF; font-weight: bold;">ForEach</span><span style="color: #000000;">&#40;</span>i <span style="color: #008000;">=&gt;</span> ItemRemoved.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>i<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; _list.<span style="color: #0000FF;">Clear</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">AddRange</span><span style="color: #000000;">&#40;</span>items<span style="color: #000000;">&#41;</span>; _list.<span style="color: #0600FF; font-weight: bold;">ForEach</span><span style="color: #000000;">&#40;</span>i <span style="color: #008000;">=&gt;</span> ItemAdded.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>i<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, OnCollectionModified<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">bool</span> Contains<span style="color: #000000;">&#40;</span>T item<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _list.<span style="color: #0000FF;">Contains</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">void</span> CopyTo<span style="color: #000000;">&#40;</span>T<span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> array, <span style="color: #2b91af; font-weight: bold;">int</span> arrayIndex<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">CopyTo</span><span style="color: #000000;">&#40;</span>array, arrayIndex<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">bool</span> Remove<span style="color: #000000;">&#40;</span>T item<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var result <span style="color: #008000;">=</span> _list.<span style="color: #0000FF;">Contains</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Remove</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; ItemRemoved.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; ItemAdded.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, OnCollectionModified<span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">return</span> result; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">int</span> Count <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _list.<span style="color: #0000FF;">Count</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">bool</span> IsReadOnly <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> false; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">int</span> IndexOf<span style="color: #000000;">&#40;</span>T item<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _list.<span style="color: #0000FF;">IndexOf</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">void</span> Insert<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">int</span> index, T item<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Insert</span><span style="color: #000000;">&#40;</span>index, item<span style="color: #000000;">&#41;</span>; ItemAdded.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Remove</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; ItemRemoved.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, OnCollectionModified<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">void</span> RemoveAt<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">int</span> index<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var item <span style="color: #008000;">=</span> _list<span style="color: #000000;">&#91;</span>index<span style="color: #000000;">&#93;</span>; _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Remove</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span>; ItemRemoved.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list.<span style="color: #0000FF;">Insert</span><span style="color: #000000;">&#40;</span>index, item<span style="color: #000000;">&#41;</span>; ItemAdded.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>item<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, OnCollectionModified<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> T <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #000000;">&#91;</span><span style="color: #2b91af; font-weight: bold;">int</span> index<span style="color: #000000;">&#93;</span> <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _list<span style="color: #000000;">&#91;</span>index<span style="color: #000000;">&#93;</span>; <span style="color: #000000;">&#125;</span> set <span style="color: #000000;">&#123;</span> var oldItem <span style="color: #008000;">=</span> _list<span style="color: #000000;">&#91;</span>index<span style="color: #000000;">&#93;</span>; _modifyCallback<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list<span style="color: #000000;">&#91;</span>index<span style="color: #000000;">&#93;</span> <span style="color: #008000;">=</span> value; ItemAdded.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>value<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">=&gt;</span> <span style="color: #000000;">&#123;</span> _list<span style="color: #000000;">&#91;</span>index<span style="color: #000000;">&#93;</span> <span style="color: #008000;">=</span> oldItem; ItemRemoved.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> EventArgs<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>oldItem<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span>, OnCollectionModified<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> OnCollectionModified<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> CollectionChanged.<span style="color: #0000FF;">Notify</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span>, EventArgs.<span style="color: #0000FF;">Empty</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> http://www.wpftutorial.net/UndoRedo.html Sat, 04 Feb 2012 19:21:28 +01002011-12-23 09:14:09 Grid Panel moc@zuehlke.com (Christian Moser) <h1>Grid Panel</h1> <p><a href="#Intro">Introduction</a></p> <p><a href="#add">How to define rows and columns</a></p> <p><a href="#add">How to add controls to the grid</a></p> <p><a href="#resize">Resize columns or rows</a></p> <p><a href="#sharedsize">How to share the width of a column over multiple grids</a></p> <p><a href="#gridlength">Using GridLenghts from code</a></p> <a name="Intro"><h2>Introduction</h2></a> <img src="images/v2_gridlayout.png" style="margin-left: 200px;" /> <p>The grid is a layout panel that arranges its child controls in a tabular structure of rows and columns. Its functionality is similar to the HTML table but more flexible. A cell can contain multiple controls, they can span over multiple cells and even overlap themselves.</p> <p>The resize behaviour of the controls is defined by the <code>HorizontalAlignment</code> and <code>VerticalAlignment</code> properties who define the anchors. The distance between the anchor and the grid line is specified by the margin of the control</p> <a name="rowscols"><h2>Define Rows and Columns</h2></a> <p>The grid has one row and column by default. To create additional rows and columns, you have to add <code>RowDefinition</code> items to the <code>RowDefinitions</code> collection and <code>ColumnDefinition</code> items to the <code>ColumnDefinitions</code> collection. The following example shows a grid with three rows and two columns.</p> <p>The size can be specified as an absolute amount of logical units, as a percentage value or automatically.</p> <table style="margin-left: 40px; width: 600px;"> <tr> <td style="width: 50px;"><b>Fixed</b></td> <td> Fixed size of logical units (1/96 inch)</td> </tr> <tr> <td><b>Auto</b></td> <td> Takes as much space as needed by the contained control</td> </tr> <tr> <td style="vertical-align: top"><b>Star (*)</b></td> <td>Takes as much space as available (after filling all auto and fixed sized columns), proportionally divided over all star-sized columns. So 3*/5* means the same as 30*/50*. Remember that star-sizing does not work if the grid size is calculated based on its content. </td> </tr> </table> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.RowDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;*&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;28&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.RowDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;200&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> </pre></div><a name="add"><h2>How to add controls to the grid</h2></a> <p>To add controls to the grid layout panel just put the declaration between the opening and closing tags of the <code>Grid</code>. Keep in mind that the row- and columndefinitions must precced any definition of child controls.</p> <p>The grid layout panel provides the two attached properties <code>Grid.Column</code> and <code>Grid.Row</code> to define the location of the control.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"><span style="color: #800000;"><span style="color: #800000;">&lt;Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.RowDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;*&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RowDefinition</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;28&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.RowDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;200&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Label</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;0&quot;</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;0&quot;</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Name:&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Label</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;1&quot;</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;0&quot;</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;E-Mail:&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Label</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;2&quot;</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;0&quot;</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Comment:&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBox</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;1&quot;</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;0&quot;</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;3&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBox</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;1&quot;</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;1&quot;</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;3&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBox</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;1&quot;</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;2&quot;</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;3&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Button</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;1&quot;</span> Grid.<span style="color: #ff0000;">Row</span>=<span style="color: #0000ff;">&quot;3&quot;</span> <span style="color: #ff0000;">HorizontalAlignment</span>=<span style="color: #0000ff;">&quot;Right&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">MinWidth</span>=<span style="color: #0000ff;">&quot;80&quot;</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;3&quot;</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Send&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> </pre></div> <a name="resize"><h2>Resizable columns or rows</h2></a> <img src="images/v2_gridsplitter.png" style="padding-left: 180px;"> <p>WPF provides a control called the <code>GridSplitter</code>. This control is added like any other control to a cell of the grid. The special thing is that is grabs itself the nearest gridline to change its width or height when you drag this control around.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"><span style="color: #800000;"><span style="color: #800000;">&lt;Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;*&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;*&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Label</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Left&quot;</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;0&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;GridSplitter</span> <span style="color: #ff0000;">HorizontalAlignment</span>=<span style="color: #0000ff;">&quot;Right&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">VerticalAlignment</span>=<span style="color: #0000ff;">&quot;Stretch&quot;</span> </span> <span style="color: #800000;"> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;1&quot;</span> <span style="color: #ff0000;">ResizeBehavior</span>=<span style="color: #0000ff;">&quot;PreviousAndNext&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;5&quot;</span> <span style="color: #ff0000;">Background</span>=<span style="color: #0000ff;">&quot;#FFBCBCBC&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Label</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Right&quot;</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;2&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> </pre></div> <p>The best way to align a grid splitter is to place it in its own auto-sized column. Doing it this way prevents overlapping to adjacent cells. To ensure that the grid splitter changes the size of the previous and next cell you have to set the <code>ResizeBehavior</code> to <code>PreviousAndNext</code>.</p> <p>The splitter normally recognizes the resize direction according to the ratio between its height and width. But if you like you can also manually set the <code> ResizeDirection</code> to <code>Columns</code> or <code>Rows</code>. <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"><span style="color: #800000;"><span style="color: #800000;">&lt;GridSplitter</span> <span style="color: #ff0000;">ResizeDirection</span>=<span style="color: #0000ff;">&quot;Columns&quot;</span><span style="color: #800000;">/&gt;</span></span> </pre></div> <a name="sharedsize"><h2>How to share the width of a column over multiple grids</h2></a> <p>The shared size feature of the grid layout allows it to synchronize the width of columns over multiple grids. The feature is very useful if you want to realize a multi-column listview by using a grid as layout panel within the data template. Because each item contains its own grid, the columns will not have the same width.</p> <p>By setting the attached property <code>Grid.IsSharedSizeScope</code> to <code>true</code> on a parent element you define a scope within the column-widths are shared.</p> <p>To synchronize the width of two columndefinitions, set the <code>SharedSizeGroup</code> to the same name.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;ItemsControl</span> Grid.<span style="color: #ff0000;">IsSharedSizeScope</span>=<span style="color: #0000ff;">&quot;True&quot;</span> <span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ItemsControl</span>.ItemTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">SharedSizeGroup</span>=<span style="color: #0000ff;">&quot;FirstColumn&quot;</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;Auto&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ColumnDefinition</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;*&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.ColumnDefinitions<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;{Binding Path=Key}&quot;</span> <span style="color: #ff0000;">TextWrapping</span>=<span style="color: #0000ff;">&quot;Wrap&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;{Binding Path=Value}&quot;</span> Grid.<span style="color: #ff0000;">Column</span>=<span style="color: #0000ff;">&quot;1&quot;</span> <span style="color: #ff0000;">TextWrapping</span>=<span style="color: #0000ff;">&quot;Wrap&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ItemsControl</span>.ItemTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ItemsControl<span style="color: #800000;">&gt;</span></span></span> </pre></div><h3>Useful Hints</h3> <p>Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto. Since TextWrapping on TextBlocks within an SharedSize column does not work you can exclude your last column from the shared size. This often helps to resolve the problem.</p> <a name="gridlength"><h2>Using GridLenghts from code</h2></a> <p>If you want to add columns or rows by code, you can use the <code>GridLength</code> class to define the differenz types of sizes.</p> <br/> <table style="margin-left: 30px;"> <tr> <td style="width: 100px;"><b>Auto sized</b></td> <td><code>GridLength.Auto</code> </td> </tr> <tr> <td><b>Star sized</b></td> <td><code>new GridLength(1,GridUnitType.Star)</td> </tr> <tr> <td><b>Fixed size</b></td> <td><code>new GridLength(100,GridUnitType.Pixel)</td> </tr> </table> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;">Grid grid <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> Grid<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; ColumnDefinition col1 <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> ColumnDefinition<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; col1.<span style="color: #0000FF;">Width</span> <span style="color: #008000;">=</span> GridLength.<span style="color: #0000FF;">Auto</span>; ColumnDefinition col2 <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> ColumnDefinition<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; col2.<span style="color: #0000FF;">Width</span> <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> GridLength<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">1</span>,GridUnitType.<span style="color: #0000FF;">Star</span><span style="color: #000000;">&#41;</span>; grid.<span style="color: #0000FF;">ColumnDefinitions</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>col1<span style="color: #000000;">&#41;</span>; grid.<span style="color: #0000FF;">ColumnDefinitions</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>col2<span style="color: #000000;">&#41;</span>; </pre></div> <h2>More on this topic</h2> <a href="GridSplitter.html">How to create a resizable column</a> http://www.wpftutorial.net/GridLayout.html Sat, 04 Feb 2012 19:21:28 +01002011-10-03 09:22:29 Introduction to WPF moc@zuehlke.com (Christian Moser) <h1>Introduction to Windows Presentation Foundation</h1> <h2>Overview</h2> <p>The Windows Presentation Foundation is Microsofts next generation UI framework to create applications with a rich user experience. It is part of the .NET framework 3.0 and higher.</p> <p>WPF combines application UIs, 2D graphics, 3D graphics, documents and multimedia into one single framework. Its vector based rendering engine uses hardware acceleration of modern graphic cards. This makes the UI faster, scalable and resolution independent.</p> <p>The followinig illustration gives you an overview of the main new features of WPF</p> <img src="images/wpfMainFeatures.png" style="padding: 10px; padding-left: 120px;" /> <h2>Separation of Appearance and Behavior</h2> <p>WPF separates the appearance of an user interface from its behavior. The appearance is generally specified in the <a href="XAML.html">Extensible Application Markup Language</a> (XAML), the behavior is implemented in a managed programming language like C# or Visual Basic. The two parts are tied together by databinding, events and commands. The separation of appearance and behavior brings the following benefits: <ul> <li>Appearance and behaviour are loosely coupled</li> <li>Designers and developers can work on separate models.</li> <li>Graphical design tools can work on simple XML documents instead of parsing code.</li> </ul> </p> <h2>Rich composition</h2> <p>Controls in WPF are extremely composable. You can define almost any type of controls as content of another. Although these flexibility sounds horrible to designers, its a very powerful feature if you use it appropriate. Put an image into a button to create an image button, or put a list of videos into a combobox to choose a video file.</p> <img style="padding-left: 150px;" src="images/playsound_button.png" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Button<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;StackPanel</span> <span style="color: #ff0000;">Orientation</span>=<span style="color: #0000ff;">&quot;Horizontal&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;speaker.png&quot;</span> <span style="color: #ff0000;">Stretch</span>=<span style="color: #0000ff;">&quot;Uniform&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;Play Sound&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/StackPanel<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Button<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>Highly customizable</h2> <p>Because of the strict separation of appearance and behavior you can easily change the look of a control. The concept of <a href="Styles.html">styles</a> let you skin controls almost like CSS in HTML. <a href="Templates.html">Templates</a> let you replace the entire appearance of a control.</p> <p>The following example shows an default WPF button and a customized button.</p> <img style="padding-left: 100px;" src="images/introduction_buttons.png" /> <h2>Resolution independence</h2> <p>All measures in WPF are logical units - not pixels. A logical unit is a 1/96 of an inch. If you increase the resolution of your screen, the user interface stays the same size - it just gets crispier. Since WPF builds on a vector based rendering engine it's incredibly easy to build scaleable user interfaces.</p> <img style="padding-left: 120px;" src="images/wpf_scaling.png" /> http://www.wpftutorial.net/WPFIntroduction.html Sat, 04 Feb 2012 19:21:28 +01002011-08-15 18:49:42 XAML moc@zuehlke.com (Christian Moser) <h1>Introduction to XAML</h1> <p>XAML stands for Extensible Application Markup Language. Its a simple language based on XML to create and initialize .NET objects with hierarchical relations. Altough it was originally invented for WPF it can by used to create any kind of object trees.</p> <p>Today XAML is used to create user interfaces in WPF, Silverlight, declare workflows in WF and for electronic paper in the XPS standard.</p> <p>All classes in WPF have parameterless constructors and make excessive usage of properties. That is done to make it perfectly fit for XML languages like XAML.</p> <h2>Advantages of XAML</h2> <p>All you can do in XAML can also be done in code. XAML ist just another way to create and initialize objects. You can use WPF without using XAML. It's up to you if you want to declare it in XAML or write it in code. Declare your UI in XAML has some advantages:</p> <ul> <li>XAML code is short and clear to read</li> <li>Separation of designer code and logic</li> <li>Graphical design tools like Expression Blend require XAML as source.</li> <li>The separation of XAML and UI logic allows it to clearly separate the roles of designer and developer.</li> </ul> <h2>XAML vs. Code</h2> <p>As an example we build a simple StackPanel with a textblock and a button in XAML and compare it to the same code in C#.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;StackPanel<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;20&quot;</span><span style="color: #800000;">&gt;</span></span>Welcome to the World of XAML<span style="color: #800000;"><span style="color: #800000;">&lt;/TextBlock<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Button</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;10&quot;</span> <span style="color: #ff0000;">HorizontalAlignment</span>=<span style="color: #0000ff;">&quot;Right&quot;</span><span style="color: #800000;">&gt;</span></span>OK<span style="color: #800000;"><span style="color: #800000;">&lt;/Button<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/StackPanel<span style="color: #800000;">&gt;</span></span></span> </pre></div><p>The same expressed in C# will look like this:</p> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #008000;">// Create the StackPanel</span> StackPanel stackPanel <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> StackPanel<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">this</span>.<span style="color: #0000FF;">Content</span> <span style="color: #008000;">=</span> stackPanel; <span style="color: #008000;">// Create the TextBlock</span> TextBlock textBlock <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> TextBlock<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; textBlock.<span style="color: #0000FF;">Margin</span> <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> Thickness<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">10</span><span style="color: #000000;">&#41;</span>; textBlock.<span style="color: #0000FF;">Text</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Welcome to the World of XAML&quot;</span>; stackPanel.<span style="color: #0000FF;">Children</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>textBlock<span style="color: #000000;">&#41;</span>; <span style="color: #008000;">// Create the Button</span> Button button <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> Button<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>; button.<span style="color: #0000FF;">Margin</span><span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> Thickness<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">20</span><span style="color: #000000;">&#41;</span>; button.<span style="color: #0000FF;">Content</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;OK&quot;</span>; stackPanel.<span style="color: #0000FF;">Children</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>button<span style="color: #000000;">&#41;</span>; </pre></div><p>As you can see is the XAML version much shorter and clearer to read. And that's the power of XAMLs expressiveness.</p> <h2>Properties as Elements</h2> <p>Properties are normally written inline as known from XML <code>&lt;Button Content="OK" /&gt;</code>. But what if we want to put a more complex object as content like an image that has properties itself or maybe a whole grid panel? To do that we can use the property element syntax. This allows us to extract the property as an own child element.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Button<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Button</span>.Content<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;Images/OK.png&quot;</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;50&quot;</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;50&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Button</span>.Content<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Button<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>Implicit Type conversion</h2> <p>A very powerful construct of WPF are implicit type converters. They do their work silently in the background. When you declare a BorderBrush, the word "Blue" is only a string. The implicit <code>BrushConverter</code> makes a <code>System.Windows.Media.Brushes.Blue</code> out of it. The same regards to the border thickness that is beeing converted implicit into a <code>Thickness</code> object. WPF includes a lot of type converters for built-in classes, but you can also write type converters for your own classses.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Border</span> <span style="color: #ff0000;">BorderBrush</span>=<span style="color: #0000ff;">&quot;Blue&quot;</span> <span style="color: #ff0000;">BorderThickness</span>=<span style="color: #0000ff;">&quot;0,10&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Border<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>Markup Extensions</h2> <p>Markup extensions are dynamic placeholders for attribute values in XAML. They resolve the value of a property at runtime. Markup extensions are surrouded by curly braces (Example: <code>Background="{StaticResource NormalBackgroundBrush}"</code>). WPF has some built-in markup extensions, but you can write your own, by deriving from <code>MarkupExtension</code>. These are the built-in markup extensions: <ul> <li><b>Binding</b><br/>To bind the values of two properties together.</li> <li><b>StaticResource</b><br/>One time lookup of a resource entry</li> <li><b>DynamicResource</b><br/>Auto updating lookup of a resource entry</li> <li><b>TemplateBinding</b><br/>To bind a property of a control template to a dependency property of the control</li> <li><b>x:Static</b><br/>Resolve the value of a static property.</li> <li><b>x:Null</b><br/>Return <code>null</code></li> </ul> The first identifier within a pair of curly braces is the name of the extension. All preciding identifiers are named parameters in the form of Property=Value. The following example shows a label whose <code>Content</code> is bound to the <code>Text</code> of the textbox. When you type a text into the text box, the text property changes and the binding markup extension automatically updates the content of the label. </p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBox</span> <span style="color: #ff0000;">x:Name</span>=<span style="color: #0000ff;">&quot;textBox&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Label</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;{Binding Text, ElementName=textBox}&quot;</span><span style="color: #800000;">/&gt;</span></span> </pre></div> <h2>Namespaces</h2> <p>At the beginning of every XAML file you need to include two namespaces. <br/>The first is <code>http://schemas.microsoft.com/winfx/2006/xaml/presentation</code>. It is mapped to all wpf controls in <code>System.Windows.Controls</code>. <br/>The second is <code>http://schemas.microsoft.com/winfx/2006/xaml</code> it is mapped to <code>System.Windows.Markup</code> that defines the XAML keywords.<br/> The mapping between an XML namespace and a CLR namespace is done by the <code>XmlnsDefinition</code> attribute at assembly level. You can also directly include a CLR namespace in XAML by using the <code>clr-namespace:</code> prefix.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Window</span> <span style="color: #ff0000;">xmlns</span>=â€http://schemas.microsoft.com/winfx/2006/xaml/presentationâ€</span> <span style="color: #800000;"> <span style="color: #ff0000;">xmlns:x</span>=â€http://schemas.microsoft.com/winfx/2006/xamlâ€<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Window<span style="color: #800000;">&gt;</span></span></span> </pre></div> http://www.wpftutorial.net/XAML.html Sat, 04 Feb 2012 19:21:28 +01002011-07-15 12:57:24 ContextMenu moc@zuehlke.com (Christian Moser) <h1>Context Menus in WPF</h1> <p>Context Menus can be defined on any WPF controls by setting the <code>ContextMenu</code> property to an instance of a <code>ContextMenu</code>. The items of a context menu are normal <code>MenuItems</code>.</p> <img style="padding: 10px; padding-left: 120px;" src='images/contextmenu.jpg' /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;RichTextBox<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RichTextBox</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ContextMenu<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Command</span>=<span style="color: #0000ff;">&quot;Cut&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span>.Icon<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;Images/cut.png&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/MenuItem</span>.Icon<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/MenuItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Command</span>=<span style="color: #0000ff;">&quot;Copy&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span>.Icon<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;Images/copy.png&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/MenuItem</span>.Icon<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/MenuItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Command</span>=<span style="color: #0000ff;">&quot;Paste&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span>.Icon<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;Images/paste.png&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/MenuItem</span>.Icon<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/MenuItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ContextMenu<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/RichTextBox</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/RichTextBox<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>Show ContextMenus on a disabled controls</h2> <p>If you rightclick on a disabled control, no context menu is shown by default. To enable the context menu for disabled controls you can set the <code>ShowOnDisabled</code> attached property of the <code>ContextMenuService</code> to <code>True</code>.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;RichTextBox</span> <span style="color: #ff0000;">IsEnabled</span>=<span style="color: #0000ff;">&quot;False&quot;</span> ContextMenuService.<span style="color: #ff0000;">ShowOnDisabled</span>=<span style="color: #0000ff;">&quot;True&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;RichTextBox</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ContextMenu<span style="color: #800000;">&gt;</span></span></span> ... <span style="color: #800000;"><span style="color: #800000;">&lt;/ContextMenu<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/RichTextBox</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/RichTextBox<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>Merge ContextMenus</h2> <p>If you want to fill a menu with items coming from multiple sources, you can use the <code>CompositeCollection</code> to merge multiple collection into one.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Window</span> <span style="color: #ff0000;">xmlns</span>=<span style="color: #0000ff;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">xmlns:x</span>=<span style="color: #0000ff;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">xmlns:sys</span>=<span style="color: #0000ff;">&quot;clr-namespace:System;assembly=mscorlib&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span> <span style="color: #ff0000;">Background</span>=<span style="color: #0000ff;">&quot;Transparent&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.Resources<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;x:Array</span> <span style="color: #ff0000;">Type</span>=<span style="color: #0000ff;">&quot;{x:Type sys:Object}&quot;</span> <span style="color: #ff0000;">x:Key</span>=<span style="color: #0000ff;">&quot;extensions&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Separator</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Extension MenuItem 1&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Extension MenuItem 2&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Extension MenuItem 3&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/x:Array<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.Resources<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ContextMenu<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ContextMenu</span>.ItemsSource<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;CompositeCollection<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Standard MenuItem 1&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Standard MenuItem 2&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Standard MenuItem 3&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;CollectionContainer</span> <span style="color: #ff0000;">Collection</span>=<span style="color: #0000ff;">&quot;{StaticResource extensions}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/CompositeCollection<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ContextMenu</span>.ItemsSource<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ContextMenu<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Window<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2 id="mvvm">How to bind a Command on a ContextMenu within a DataTemplate using MVVM</h2> <p>Since the <code>Popuup</code> control has it's separate visual tree, you cannot use find ancestor to find the <code>Grid</code>. The trick here is to use the <code>PlacementTarget</code> property, that contains the element, the ContextMenu is aligned to, what is the <code>Grid</code> in our case.</p> <p>But this is only half of the solution. Because of the data template, the <code>DataContext</code> is set to a dataitem, and not the view model. So you need another relative source lookup, to find the view model. Trick Nr. 2 is to use the <code>Tag</code> property to bind the view model from outside to the grid, which is the <code>PlacementTarget</code> used above. And there we are.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span> <span style="color: #ff0000;">Tag</span>=<span style="color: #0000ff;">&quot;{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ContextMenu</span> <span style="color: #ff0000;">DataContext</span>=<span style="color: #0000ff;">&quot;{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Cut&quot;</span> <span style="color: #ff0000;">Command</span>=<span style="color: #0000ff;">&quot;{Binding CutCommand}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Copy&quot;</span> <span style="color: #ff0000;">Command</span>=<span style="color: #0000ff;">&quot;{Binding CopyCommand}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;MenuItem</span> <span style="color: #ff0000;">Content</span>=<span style="color: #0000ff;">&quot;Paste&quot;</span> <span style="color: #ff0000;">Command</span>=<span style="color: #0000ff;">&quot;{Binding PasteCommand}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ContextMenu<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid</span>.ContextMenu<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>How to open a context menu from code</h2> <p>The following sample shows you how to open a context menu of a control programmatically:</p> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> OpenContextMenu<span style="color: #000000;">&#40;</span>FrameworkElement element<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span> element.<span style="color: #0000FF;">ContextMenu</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> element.<span style="color: #0000FF;">ContextMenu</span>.<span style="color: #0000FF;">PlacementTarget</span> <span style="color: #008000;">=</span> element; element.<span style="color: #0000FF;">ContextMenu</span>.<span style="color: #0000FF;">IsOpen</span> <span style="color: #008000;">=</span> true; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> http://www.wpftutorial.net/ContextMenu.html Sat, 04 Feb 2012 19:21:28 +01002011-05-23 08:36:43 ListBox moc@zuehlke.com (Christian Moser) <h1>WPF ListBox Control</h1> <img style="padding-left: 80px;" src="images/listbox1.png" /> <h2>Introduction</h2> <p>The ListBox control displays a list of items. The user can select one or multiple items depending on the selection mode. The typical usage of a listbox in WPF is to bind its items to a list of business objects and display them by applying a data template.</p> <br/> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;ListBox</span> <span style="color: #ff0000;">Margin</span>=<span style="color: #0000ff;">&quot;20&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ListBoxItem<span style="color: #800000;">&gt;</span></span></span>New York<span style="color: #800000;"><span style="color: #800000;">&lt;/ListBoxItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ListBoxItem<span style="color: #800000;">&gt;</span></span></span>Los Angeles<span style="color: #800000;"><span style="color: #800000;">&lt;/ListBoxItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ListBoxItem<span style="color: #800000;">&gt;</span></span></span>Paris<span style="color: #800000;"><span style="color: #800000;">&lt;/ListBoxItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ListBoxItem<span style="color: #800000;">&gt;</span></span></span>Zürich<span style="color: #800000;"><span style="color: #800000;">&lt;/ListBoxItem<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ListBox<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>How to define a Trigger for IsSelected in the DataTemplate</h2> <p>If you want to change the appearance of a ListBoxItem when it is selected, you have to bind the IsSelected property of the ListBoxItem. But this is a bit tricky, you have to use a relative source with FindAcestor to navigate up the visual tree until you reach the ListBoxItem.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate</span> <span style="color: #ff0000;">x:Key</span>=<span style="color: #0000ff;">&quot;myDataTemplate&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Border</span> <span style="color: #ff0000;">x:Name</span>=<span style="color: #0000ff;">&quot;border&quot;</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;50&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;{Binding Text}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Border<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate</span>.Triggers<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTrigger</span> <span style="color: #ff0000;">Binding</span>=<span style="color: #0000ff;">&quot;{Binding RelativeSource=</span> <span style="color: #800000;"> {RelativeSource Mode=FindAncestor, AncestorType=</span> <span style="color: #800000;"> {x:Type ListBoxItem}},Path=IsSelected}&quot;</span> <span style="color: #ff0000;">Value</span>=<span style="color: #0000ff;">&quot;True&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Setter</span> <span style="color: #ff0000;">TargetName</span>=<span style="color: #0000ff;">&quot;border&quot;</span> <span style="color: #ff0000;">Property</span>=<span style="color: #0000ff;">&quot;Height&quot;</span> <span style="color: #ff0000;">Value</span>=<span style="color: #0000ff;">&quot;100&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTrigger<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate</span>.Triggers<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>More articles about the ListBox</h2> [sublist] http://www.wpftutorial.net/ListBox.html Sat, 04 Feb 2012 19:21:28 +01002011-05-23 08:36:27 Designtime vs. Runtime moc@zuehlke.com (Christian Moser) <h1>Designtime vs. Runtime</h1> <h2>Introduction</h2> <p>An application often looks great at runtime, but when you open it in a designer like VisualStudio or Expression Blend, the experience is quite different. The rason is that at designtime: <ul> <li><b>UserControls are not embedded in a parent view</b> <ul> <li>Width and Height are not set</li> </ul> </li> <li><b>Constructor of the root-element is not called</b> <ul> <li>Root Element is replaced by the designer</li> <li>ViewModel is not created</li> </ul> <li><b>Controls behave different</b> <ul> <li>No mouse and keyboard events</li> <li>Design time extensions loaded</li> </ul> </li> </ul> This can be kind of annoying, especially if you want to edit data templates or layout controls.</p> <img src="images/designtimevsruntime.png" style="margin-left: 50px;" /> <h2>Designtime attributes</h2> <p>To improve the design experience, Microsoft provides special designtime attributes that can be added to any WPF element and serve as a hint for the design tool.</p> <p>The designtime attributes are defined in a special namespace, that is usually mapped to the <code>d:</code> prefix. To tell the XAML parser not to interprete these attributes at runtime, the markup compatibility namespace is mapped to <code>mc:</code> and with the <code>mc:Ignorable="d"</code> instruction, the <code>d:</code> namespace is excluded.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Window</span> </span> <span style="color: #800000;"> xmlns:d =<span style="color: #0000ff;">&quot;http://schemas.microsoft.com/expression/blend/2008&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">xmlns:mc</span>=<span style="color: #0000ff;">&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">mc:Ignorable</span>=<span style="color: #0000ff;">&quot;d&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> <h2><code>d:DesignHeight</code> and <code>d:DesignWidth</code></h2> <p>The <code>d:DesignHeight</code> and <code>d:DesignWidth</code> sets a fixed height and width for the element at designtime</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;UserControl</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">xmlns</span>=<span style="color: #0000ff;">&quot;http://schemas.microsoft.com/...&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">xmlns:x</span>=<span style="color: #0000ff;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span> <span style="color: #800000;"> <span style="color: #ff0000;">d:DesignWidth</span>=<span style="color: #0000ff;">&quot;640&quot;</span> <span style="color: #ff0000;">d:DesignHeight</span>=<span style="color: #0000ff;">&quot;480&quot;</span> <span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;UserControl</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> <h2><code>d:LayoutOverrides</code></h2> <p>If a property is set to a fixed value at runtime, but you want to override it at designtime, you can use the <code>d:LayoutOverrides</code> attribute. All properties that should be ignored at designtime can be listed, separated by a semicolon.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;Border</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;250&quot;</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;160&quot;</span> <span style="color: #ff0000;">d:LayoutOverrides</span>=<span style="color: #0000ff;">&quot;Width, Height&quot;</span> <span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Border<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h2>Additional Resources</h2> <a href="http://msdn.microsoft.com/en-us/library/ff602277(v=vs.95).aspx">MSDN Designtime-attributes</a> <p><b>This article is still under construction</b></p> http://www.wpftutorial.net/DesigntimeVsRuntime.html Sat, 04 Feb 2012 19:21:28 +01002011-05-04 15:22:02 Styling moc@zuehlke.com (Christian Moser) <h1>Templates and Styles</h1> <p>One of WPF's most powerful feature is the ability to completely replace the look and feel of user interface elements.</p> <h2>Styles</h2> <p>The concept of styles let you remove all properties values from the individual user interface elements and combine them into a style. A style consists of a list of property setters. If you apply a style it <strong>sets the properties on the user interface element</strong> to the styles' values. The idea is quite similar to Cascading Styles Sheets (CSS) in web development.<br/> Using styles gives you the following advantages: <ul> <li>Removes redundancy from your code</li> <li>Let you change the appearance of a set of controls from a single point</li> <li>Gives you the possibility to swap the style at runtime</li> </ul> </p> <a class="articleref" href="Styles.html">Learn more about Styles</a> <h2>Templates</h2> <p>An element like a button consists of multpiple composed parts: A border, a chrome and a content presenter. With styles you can only change the appearance from "outside" by setting public properties. With a template you can <b>replace parts inside a user interface element.</b>.<br/> Using templates gives you the following advantages: <ul> <li>Change the parts inside a user interface element</li> <li>Reduce the numbers custom controls</li> </ul> </p> <a class="articleref" href="Templates.html">Learn more about Templates</a> http://www.wpftutorial.net/TemplatesStyles.html Sat, 04 Feb 2012 19:21:28 +01002011-05-03 10:40:49 Drag & Drop moc@zuehlke.com (Christian Moser) <h1>Drag and Drop in WPF</h1> <h2>Introduction</h2> <p>Drag&Drop can drasticly improve the productiviy and user experience of a software. But only a few programmers provide drag and drop functionality in their applications, because they think its much more dificult than it really is. This article shows how simple drag and drop can be implemented in WPF.</p> <h2>Drag&Drop in 6 Steps</h2> <ol> <li>Detect a drag as a combinatination of <b>MouseMove</b> and <b>MouseLeftButtonDown</b></li> <li>Find the data you want to drag and create a <b>DataObject</b> that contains the format, the data and the allowed effects.</li> <li>Initiate the dragging by calling <b>DoDragDrop()</b></li> <li>Set the <b>AllowDrop</b> property to <b>True</b> on the elements you want to allow dropping.</li> <li>Register a handler to the <b>DragEnter</b> event to detect a dragging over the drop location. Check the format and the data by calling <b>GetDataPresent()</b> on the event args. If the data can be dropped, set the <b>Effect</b> property on the event args to display the appropriate mouse cursor.</li> <li>When the user releases the mouse button the <b>DragDrop</b> event is called. Get the data by calling the <b>GetData()</b> method on the <b>Data</b> object provided in the event args.</b> </ol> <p>...and that's all the magic.</p> <h2>Drag</h2> <p>To start the drag operation, we have to detect a mouse move while the left mouse button is pressed. To do this we have to hook up handlers on the <code>PreviewMouseMove</code> and <code>PreviewMouseLeftButtonDown</code> events.</p> <p>To prevent occasionally drags, its a good design to not start the drag operation until the user has moved the mouse cursor by a couple of pixels. WPF provides a constant that contains the amount of pixel that Windows uses.</p> <p>When the drag is initiated, we need to specify the data we want to drag. In our case its the data of the <code>ListViewItem</code> we dragged. We find the <code>ListViewItem</code> in the <code>OriginalSource</code> of the mouse event args. By calling <code>ItemContainerGenerator.ItemFromContainer</code> we get the data behind the <code>ListViewItem</code>.</p> <p>Create a <code>DataObject</code> to transport the data to the drop location. The constructor takes two arguments. A string that describes the format and the data we want to drag.</p> <br/> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;ListView</span> <span style="color: #ff0000;">x:Name</span>=<span style="color: #0000ff;">&quot;DragList&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">PreviewMouseLeftButtonDown</span>=<span style="color: #0000ff;">&quot;List_PreviewMouseLeftButtonDown&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">PreviewMouseMove</span>=<span style="color: #0000ff;">&quot;List_MouseMove&quot;</span><span style="color: #800000;">/&gt;</span></span> </pre></div> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> List_PreviewMouseLeftButtonDown<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">object</span> sender, MouseButtonEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #008000;">// Store the mouse position</span> startPoint <span style="color: #008000;">=</span> e.<span style="color: #0000FF;">GetPosition</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> </pre></div> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> List_MouseMove<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">object</span> sender, MouseEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #008000;">// Get the current mouse position</span> Point mousePos <span style="color: #008000;">=</span> e.<span style="color: #0000FF;">GetPosition</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>; Vector diff <span style="color: #008000;">=</span> startPoint <span style="color: #008000;">-</span> mousePos; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">LeftButton</span> <span style="color: #008000;">==</span> MouseButtonState.<span style="color: #0000FF;">Pressed</span> <span style="color: #008000;">&amp;&amp;</span> Math.<span style="color: #0000FF;">Abs</span><span style="color: #000000;">&#40;</span>diff.<span style="color: #0000FF;">X</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">&gt;</span> SystemParameters.<span style="color: #0000FF;">MinimumHorizontalDragDistance</span> || Math.<span style="color: #0000FF;">Abs</span><span style="color: #000000;">&#40;</span>diff.<span style="color: #0000FF;">Y</span><span style="color: #000000;">&#41;</span> <span style="color: #008000;">&gt;</span> SystemParameters.<span style="color: #0000FF;">MinimumVerticalDragDistance</span> <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #008000;">// Get the dragged ListViewItem</span> ListView listView <span style="color: #008000;">=</span> sender <span style="color: #0600FF; font-weight: bold;">as</span> ListView; ListViewItem listViewItem <span style="color: #008000;">=</span> FindAnchestor<span style="color: #008000;">&lt;</span>ListViewItem<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#40;</span>DependencyObject<span style="color: #000000;">&#41;</span>e.<span style="color: #0000FF;">OriginalSource</span><span style="color: #000000;">&#41;</span>; <span style="color: #008000;">// Find the data behind the ListViewItem</span> Contact contact <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>Contact<span style="color: #000000;">&#41;</span>listView.<span style="color: #0000FF;">ItemContainerGenerator</span>. <span style="color: #0000FF;">ItemFromContainer</span><span style="color: #000000;">&#40;</span>listViewItem<span style="color: #000000;">&#41;</span>; <span style="color: #008000;">// Initialize the drag &amp; drop operation</span> DataObject dragData <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> DataObject<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;myFormat&quot;</span>, contact <span style="color: #000000;">&#41;</span>; DragDrop.<span style="color: #0000FF;">DoDragDrop</span><span style="color: #000000;">&#40;</span>listViewItem, dragData, DragDropEffects.<span style="color: #0000FF;">Move</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #008000;">// Helper to search up the VisualTree</span> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">static</span> T FindAnchestor<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #000000;">&#40;</span>DependencyObject current<span style="color: #000000;">&#41;</span> where T <span style="color: #008000;">:</span> DependencyObject <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">do</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span> current <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">is</span></a> T <span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #000000;">&#40;</span>T<span style="color: #000000;">&#41;</span>current; <span style="color: #000000;">&#125;</span> current <span style="color: #008000;">=</span> VisualTreeHelper.<span style="color: #0000FF;">GetParent</span><span style="color: #000000;">&#40;</span>current<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">while</span> <span style="color: #000000;">&#40;</span>current <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">return</span> null; <span style="color: #000000;">&#125;</span> </pre></div> <h2>Drop</h2> <p>To make an element be a drop location, set the <b>AllowDrop</b> property to true. When the user drags an item over the element, the <b>DragEnter</b> event is called. In this event you can analyze the data and decide if a drop is allowed or not.</p> <p>When the user releases the mouse button the <b>Drop</b> event is called. The data is available in the <b>DataObject</b> provided in the DragEventArgs.</p> <br/> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;ListView</span> <span style="color: #ff0000;">x:Name</span>=<span style="color: #0000ff;">&quot;DropList&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">Drop</span>=<span style="color: #0000ff;">&quot;DropList_Drop&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">DragEnter</span>=<span style="color: #0000ff;">&quot;DropList_DragEnter&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">AllowDrop</span>=<span style="color: #0000ff;">&quot;True&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> DropList_DragEnter<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">object</span> sender, DragEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span>e.<span style="color: #0000FF;">Data</span>.<span style="color: #0000FF;">GetDataPresent</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;myFormat&quot;</span><span style="color: #000000;">&#41;</span> || sender <span style="color: #008000;">==</span> e.<span style="color: #0000FF;">Source</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> e.<span style="color: #0000FF;">Effects</span> <span style="color: #008000;">=</span> DragDropEffects.<span style="color: #0000FF;">None</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #0600FF; font-weight: bold;">void</span> DropList_Drop<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">object</span> sender, DragEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span>e.<span style="color: #0000FF;">Data</span>.<span style="color: #0000FF;">GetDataPresent</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;myFormat&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> Contact contact <span style="color: #008000;">=</span> e.<span style="color: #0000FF;">Data</span>.<span style="color: #0000FF;">GetData</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;myFormat&quot;</span><span style="color: #000000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> Contact; ListView listView <span style="color: #008000;">=</span> sender <span style="color: #0600FF; font-weight: bold;">as</span> ListView; listView.<span style="color: #0000FF;">Items</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>contact<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> http://www.wpftutorial.net/DragAndDrop.html Sat, 04 Feb 2012 19:21:28 +01002011-04-19 16:59:14 DataGrid moc@zuehlke.com (Christian Moser) <h1>WPF DataGrid Control</h1> <div style="text-align:right;"> <a href="uploads/DataGrid.zip"><img src="images/download_sample.png"></a> </div> <h2>Introduction</h2> <p>Since .NET 4.0, Microsoft is shipping a DataGrid control that provides all the basic functionality needed, like: <ul> <li><a href="#autoColumns">Auto generation of columns</a></li> <li><a href="#manualColumns">Manual definition of columns</a></li> <li><a href="#selection">Selection</a></li> <li><a href="#grouping">Grouping</a></li> <li><a href="#columnFeatures">Column sorting, reordering and resizing</a></li> <li><a href="#rowDetails">Row Details</a></li> <li><a href="#altbackgnd">Alternating BackgroundBrush</a></li> <li><a href="#frozenColumns">Frozen columns</a></li> <li><a href="#headers">Headers Visibility</a></li> <li><a href="#templateAutoColumns">How to template autogenerated columns</a></li> </ul> <br/> <a name="autoColumns"><h2>Basic usage: Auto generate columns</h2></a> <p>To show a basic data grid , just drop a <code>DataGrid</code> control to your view and bind the <code>ItemsSource</code> to a collection of data objects and you're done. The DataGrid provides a feature called <code>AutoGenerateColumns</code> that automatically generates column according to the public properties of your data objects. It generates the following types of columns: <ul> <li>TextBox columns for string values</li> <li>CheckBox columns for boolean values</li> <li>ComboBox columns for enumerable values</li> <li>Hyperlink columns for Uri values</li> </ul> </p> <img src="images/datagrid1.png" style="padding-left: 30px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div><br/> <a name="manualColumns"><h2>Manually define columns</h2></a> <p>Alternatively you can define your columns manually by setting the <code>AutoGenerateColumns</code> property to <code>False</code>. In this case you have to define the columns in the <code>Columns</code> collection of the data grid. You have the following types of columns available: <ul> <li><code>DataGridCheckBoxColumn</code> for boolean values</li> <li><code>DataGridComboBoxColumn</code> for enumerable values</li> <li><code>DataGridHyperlinkColumn</code> for Uri values</li> <li><code>DataGridTemplateColumn</code> to show any types of data by defining your own cell template</li> <li><code>DataGridTextColumn</code> to show text values</li> </ul> </p> <img src="images/datagrid2.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> <span style="color: #ff0000;">AutoGenerateColumns</span>=<span style="color: #0000ff;">&quot;False&quot;</span> <span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span>.Columns<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGridTemplateColumn</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;Image&quot;</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;SizeToCells&quot;</span> <span style="color: #ff0000;">IsReadOnly</span>=<span style="color: #0000ff;">&quot;True&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGridTemplateColumn</span>.CellTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;{Binding Image}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGridTemplateColumn</span>.CellTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGridTemplateColumn<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid</span>.Columns<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid<span style="color: #800000;">&gt;</span></span></span> </pre></div><br/> <a name="selection"><h2>Selection</h2></a> <p>The data grid includes a variety of selection modes. They are configured by the <code>SelectionMode</code> and <code>SelectionUnit</code> property.</p> <ul> <li>The <b><code>SelectionMode</code></b> can be set to <code>Single</code> or <code>Extended</code> to define if one or multiple units can be selected simultaneously.</li> <li>The <b><code>SelectionUnit</code></b> defines the scope of one selection unit. It can be set to <code>Cell</code>, <code>CellAndRowHeader</code> and <code>FullRow</code>.</li> </ul> <img src="images/datagrid3.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">SelectionMode</span>=<span style="color: #0000ff;">&quot;Extended&quot;</span> <span style="color: #ff0000;">SelectionUnit</span>=<span style="color: #0000ff;">&quot;Cell&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div><br/> <a name="columnFeatures"><h2>Column sorting, reordering and resizing</h2></a> <p>The data grid provides features to sort, reorder and resize columns. They can be enabled or disabled by the following properties: <ul> <li><code>CanUserReorderColumns</code> enables or disables column re-ordering</li> <li><code>CanUserResizeColumns</code> enables or disables column resizing</li> <li><code>CanUserResizeRows</code> enables or disables row resizing</li> <li><code>CanUserSortColumns</code> enables or disables column sorting</li> </ul> </p> <img src="images/datagrid4.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">CanUserReorderColumns</span>=<span style="color: #0000ff;">&quot;True&quot;</span> <span style="color: #ff0000;">CanUserResizeColumns</span>=<span style="color: #0000ff;">&quot;True&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">CanUserResizeRows</span>=<span style="color: #0000ff;">&quot;False&quot;</span> <span style="color: #ff0000;">CanUserSortColumns</span>=<span style="color: #0000ff;">&quot;True&quot;</span><span style="color: #800000;">/&gt;</span></span> </pre></div><br/> <a name="grouping"><h2>Grouping</h2></a> <p>The data grid also supports grouping. To enable grouping you have to define a <code>CollectionView</code> that contains to least one <code>GroupDescription</code> that defines the criterias how to group.</p> <img src="images/datagrid6.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> Customers <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> ListCollectionView<span style="color: #000000;">&#40;</span>_customers<span style="color: #000000;">&#41;</span>; Customers.<span style="color: #0000FF;">GroupDescriptions</span>.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> PropertyGroupDescription<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Gender&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; </pre></div> <p>Second thing you need to do is defining a template how the groups should look like. You can do this by setting the <code>GroupStyle</code> to something like the following snippet.</p> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding GroupedCustomers}&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span>.GroupStyle<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;GroupStyle<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;GroupStyle</span>.HeaderTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;StackPanel<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;{Binding Path=Name}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/StackPanel<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/GroupStyle</span>.HeaderTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;GroupStyle</span>.ContainerStyle<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Style</span> <span style="color: #ff0000;">TargetType</span>=<span style="color: #0000ff;">&quot;{x:Type GroupItem}&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Setter</span> <span style="color: #ff0000;">Property</span>=<span style="color: #0000ff;">&quot;Template&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Setter</span>.Value<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ControlTemplate</span> <span style="color: #ff0000;">TargetType</span>=<span style="color: #0000ff;">&quot;{x:Type GroupItem}&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Expander<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Expander</span>.Header<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;StackPanel</span> <span style="color: #ff0000;">Orientation</span>=<span style="color: #0000ff;">&quot;Horizontal&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;{Binding Path=Name}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;{Binding Path=ItemCount}&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;TextBlock</span> <span style="color: #ff0000;">Text</span>=<span style="color: #0000ff;">&quot;Items&quot;</span><span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/StackPanel<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Expander</span>.Header<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;ItemsPresenter</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Expander<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/ControlTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Setter</span>.Value<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Setter<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Style<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/GroupStyle</span>.ContainerStyle<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/GroupStyle<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid</span>.GroupStyle<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid<span style="color: #800000;">&gt;</span></span></span> </pre></div> <br/> <a name="rowDetails"><h2>Row Details</h2></a> <p>The data grid provides a feature that shows a detail panel for a selected row. It can be enabled by setting a DataTemplate to the <code>RowDetailsTemplate</code> property. The data template gets the object that is bound to this row passed by the DataContext and can bind to it.</p> <img src="images/datagrid5.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span>.Columns<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGridTextColumn</span> <span style="color: #ff0000;">Header</span>=<span style="color: #0000ff;">&quot;First Name&quot;</span> <span style="color: #ff0000;">Binding</span>=<span style="color: #0000ff;">&quot;{Binding FirstName}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid</span>.Columns<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span>.RowDetailsTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Height</span>=<span style="color: #0000ff;">&quot;100&quot;</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;{Binding Image}&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid</span>.RowDetailsTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataGrid<span style="color: #800000;">&gt;</span></span></span> </pre></div> <h3>Row Details depending on the type of data</h3> <p>You can specify a <code>RowDetailsTemplateSelector</code> that selects a data template according to the type or data that this row contains. To do this, create a type that derives from <code>DataTemplateSelector</code> and override the <code>SelectTemplate</code> method. In the <code>items</code> argument you get the data and you can determine which data template to display. Return an instance of that data template as return value.</p> <img src="images/datagrid7.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">class</span> GenderTemplateSelector <span style="color: #008000;">:</span> DataTemplateSelector <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">public</span> DataTemplate MaleTemplate <span style="color: #000000;">&#123;</span> get; set; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> DataTemplate FemaleTemplate <span style="color: #000000;">&#123;</span> get; set; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">override</span> DataTemplate SelectTemplate<span style="color: #000000;">&#40;</span><span style="color: #2b91af; font-weight: bold;">object</span> item, DependencyObject container<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> var customer <span style="color: #008000;">=</span> item <span style="color: #0600FF; font-weight: bold;">as</span> Customer; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #000000;">&#40;</span>customer <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">base</span>.<span style="color: #0000FF;">SelectTemplate</span><span style="color: #000000;">&#40;</span>item, container<span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">if</span><span style="color: #000000;">&#40;</span> customer.<span style="color: #0000FF;">Gender</span> <span style="color: #008000;">==</span> Gender.<span style="color: #0000FF;">Male</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> MaleTemplate; <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">return</span> FemaleTemplate; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div><br/> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;l:GenderTemplateSelector</span> <span style="color: #ff0000;">x:Key</span>=<span style="color: #0000ff;">&quot;genderTemplateSelector&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;l:GenderTemplateSelector</span>.MaleTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span> <span style="color: #ff0000;">Background</span>=<span style="color: #0000ff;">&quot;LightBlue&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;{Binding Image}&quot;</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;50&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/l:GenderTemplateSelector</span>.MaleTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;l:GenderTemplateSelector</span>.FemaleTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Grid</span> <span style="color: #ff0000;">Background</span>=<span style="color: #0000ff;">&quot;Salmon&quot;</span><span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;Image</span> <span style="color: #ff0000;">Source</span>=<span style="color: #0000ff;">&quot;{Binding Image}&quot;</span> <span style="color: #ff0000;">Width</span>=<span style="color: #0000ff;">&quot;50&quot;</span> <span style="color: #800000;">/&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/Grid<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/DataTemplate<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/l:GenderTemplateSelector</span>.FemaleTemplate<span style="color: #800000;">&gt;</span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;/l:GenderTemplateSelector<span style="color: #800000;">&gt;</span></span></span> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">RowDetailsTemplateSelector</span>=<span style="color: #0000ff;">&quot;{StaticResource genderTemplateSelector}&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> <a name="altbackgnd"><h2>Alternating BackgroundBrush</h2></a> <p>You can define a an <code>AlternatingRowBackground</code> that is applied every even row. You can additionally specify an <code>AlternationCount</code> if you only want to ink every every n-th data row.</p> <img src="images/datagrid8.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">AlternatingRowBackground</span>=<span style="color: #0000ff;">&quot;Gainsboro&quot;</span> <span style="color: #ff0000;">AlternationCount</span>=<span style="color: #0000ff;">&quot;2&quot;</span><span style="color: #800000;">/&gt;</span></span> </pre></div> <a name="frozenColumns"><h2>Frozen Columns</h2></a> <p>The data grid also supports the feature to freeze columns. That means they stay visible while you scoll horizontally through all columns. This is a useful feature to keep a referencing column like an ID or a name always visible to keep your orientation while scrolling.</p> <p>To freeze a numer of columns just set the <code>FrozenColumnCount</code> property to the number of columns you want to freeze.</p> <img src="images/datagrid9.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> <span style="color: #ff0000;">FrozenColumnCount</span>=<span style="color: #0000ff;">&quot;2&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> <a name="headers"><h2>Headers visbility</h2></a> <p>You can control the visibility of row and column headers by setting the <code>HeadersVisibility</code> property to either <code>None</code>,<code>Row</code>,<code>Column</code> or <code>All</code></p> <img src="images/datagrid10.png" style="padding-left: 100px;" /> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;DataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding Customers}&quot;</span> <span style="color: #ff0000;">HeadersVisibility</span>=<span style="color: #0000ff;">&quot;None&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> <h2 id="templateAutoColumns">How to template autogenerated columns</h2> <p>If you want to autogenerate columns using <code>AutoGenerateColumns="True"</code>, you cannot use <code>CellTemplates</code>, because the <code>DataGrid</code> autogenerates either a text, combo, hyperlink or checkbox column, but none of these are templateable. A simple workaround is to hook into the autogeneration, cancel it and always create a <code>DataGridTemplateColumn</code>. The following snippet shows the idea (the code is just a draft): <div class="codeblock"><pre class="csharp csharp" style="font-family: courier new,courier,monospace;"> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #2b91af; font-weight: bold;">class</span> MyDataGrid <span style="color: #008000;">:</span> DataGrid <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">public</span> DataTemplateSelector CellTemplateSelector <span style="color: #000000;">&#123;</span> get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #000000;">&#40;</span>DataTemplateSelector<span style="color: #000000;">&#41;</span>GetValue<span style="color: #000000;">&#40;</span>CellTemplateSelectorProperty<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> set <span style="color: #000000;">&#123;</span> SetValue<span style="color: #000000;">&#40;</span>CellTemplateSelectorProperty, value<span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #0600FF; font-weight: bold;">readonly</span> DependencyProperty CellTemplateSelectorProperty <span style="color: #008000;">=</span> DependencyProperty.<span style="color: #0000FF;">Register</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Selector&quot;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">typeof</span></a><span style="color: #000000;">&#40;</span>DataTemplateSelector<span style="color: #000000;">&#41;</span>, <a href="http://www.google.com/search?q=typeof+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">typeof</span></a><span style="color: #000000;">&#40;</span>MyDataGrid<span style="color: #000000;">&#41;</span>, <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> FrameworkPropertyMetadata<span style="color: #000000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>; <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #0600FF; font-weight: bold;">void</span> OnAutoGeneratingColumn<span style="color: #000000;">&#40;</span>DataGridAutoGeneratingColumnEventArgs e<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> e.<span style="color: #0000FF;">Cancel</span> <span style="color: #008000;">=</span> true; Columns.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span><a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #0000ff; font-weight: bold;">new</span></a> DataGridTemplateColumn <span style="color: #000000;">&#123;</span> Header <span style="color: #008000;">=</span> e.<span style="color: #0000FF;">Column</span>.<span style="color: #0000FF;">Header</span>, CellTemplateSelector <span style="color: #008000;">=</span> CellTemplateSelector <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span>; <span style="color: #000000;">&#125;</span> <span style="color: #000000;">&#125;</span> </pre></div> <div class="codeblock"><pre class="xaml xaml" style="font-family: courier new,courier,monospace;"> <span style="color: #800000;"><span style="color: #800000;">&lt;l:MyDataGrid</span> <span style="color: #ff0000;">ItemsSource</span>=<span style="color: #0000ff;">&quot;{Binding}&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">AutoGenerateColumns</span>=<span style="color: #0000ff;">&quot;True&quot;</span> </span> <span style="color: #800000;"> <span style="color: #ff0000;">CellTemplateSelector</span>=<span style="color: #0000ff;">&quot;{StaticResource templateSelector}&quot;</span> <span style="color: #800000;">/&gt;</span></span> </pre></div> http://www.wpftutorial.net/DataGrid.html Sat, 04 Feb 2012 19:21:28 +01002011-04-19 08:55:41 Debugging Animations moc@zuehlke.com (Christian Moser) <h1>Debugging style and template Errors</h1> <h3>Common Errors</h3> <p>If you get the following error: <code>Cannot animate ... on an immutable object instance.</code> it could be that you are run into one of the following issues:</p> <ul> <li>You are animating a dependency property without having a value set</li> <li>You are animating a dependency property who's value is resolved by a DynamicResource</li> <li>You are animating a dependency property who's current value is defined in another assembly that is not merged into the resource dictionary.</li> <li>You are animating a value that is currently databound</li> <li>You have an invalid property path specified.</li> </ul> http://www.wpftutorial.net/DebuggingAnimations.html Sat, 04 Feb 2012 19:21:28 +01002011-03-24 17:42:20 WPF Troubleshooting moc@zuehlke.com (Christian Moser) <h1>WPF Troubleshooting</h1> <div style="width: 700px;"> <p>During my time as a consultant I noticed, that there were typical traps in WPF, where developers can loose a lot of time. So I decided to make a hitlist of the most common mistakes and solutions how to resolve them. I hope this helps.</p> <h2>Layout</h2> <ul> <li><b>Scrollbar is not active or visible</b><br/> <ul> <li>If your control is within a vertical stackpanel, it gives the control infinite height to layout. Consider replacing the stackpanel by a dockpanel.</li> </ul><br/> </li> <li><b>I created a data template and set HorizontalAlignment to Stretch but the item is not stretched</b> <ul> <li>Set the <code>HorizontalContentAlignment</code> on the list to <code>Stretch</code></li> </ul> </li> </ul> <h2>DataBinding</h2> <ul> <li><b>I changed a value, but the binding is not reflecting my changes</b> <ul> <li>Check the output window in VisualStudio, if there are any binding errors.</li> <li>Does your data support INotifyPropertyChanged?</li> <li>Just firing a PropertyChanged event without changing the data does not work. Because the binding checks if oldvalue!=newvalue</li> </ul> </li> </ul> <h2>Performance</h2> <ul> <li><b>My list of items takes too long to render</b><br/> <ul> <li>Your list is not virtualized. This means, all items will be generated, even if they are not visible. To avoid this check the following points: <ul style="list-style-type: circle;"> <li><code>ScrollViewer.CanContentScrol</code> must be set to <code>False</code></li> <li>Grouping must be disabled</li> <li>You replaced the ItemsPanel by one that does not support virtualization</li> </ul> </li> <li>You are using a too complex data template.</li> </ul><br/> </li> <li><b>Animations cause a high CPU load.</b><br/> <ul> <li>WPF cannot use hardware acceleration and does software rendering. This can be because of the following points: <ul style="list-style-type: circle;"> <li>You have set <code>AllowTransparency</code> to <code>True</code> on your window.</li> <li>You are using legacy <code>BitmapEffects</code> instead of fast pixel shaders (<code>Effects</code>).</li> <li>Your graphics adapter or driver does not support DirectX</li> </ul> </li> </ul> </li> </ul> <h2>Custom Controls</h2> <ul> <li><b>I created a custom control, but the template it not showing</b><br/> <ul> <li>Check if you have overriden the metadata of the <code>DefaultStyleKeyProperty</code> and set it to your type.</li> <li>Check if your template is surrounded by a style and both have the right <code>TargetType</code></li> <li>Check if the resource dictionary that contains the default style is loaded</li> </ul><br/> </li> <li><b>I use {TemplateBinding} in my ControlTemplate, but is not working</b><br/> <ul> <li>In most cases you have to replace <code>{TemplateBinding Property}</code> by <code>{Binding Property RelativeSource={RelativeSource TemplatedParent}}</code></li> <li>You can only use TemplateBinding within the content of your control template. It will not work anywhere else!</li> <li>If you want to access a parent property in the trigger, you have to use a normal binding, with relative source Self.</li> <li>TemplateBinding works only within the VisualTree of the template. You cannot use it on items that are only in the logical tree. Neighter on Freezables or to do two-way binding.</li> </ul> </ul> </div> http://www.wpftutorial.net/Troubleshooter.html Sat, 04 Feb 2012 19:21:28 +01002011-03-23 07:02:53 WPF Inspector moc@zuehlke.com (Christian Moser) <h1>WPF Inspector</h1> <img src="images/inspector_ad.jpg" /> <p>WPF Inspector is a utility that attaches to a running WPF application to troubleshoot common problems with layouting, databinding or styling. WPF Inspector allows you to explore a live view of the logical- and visual tree, read and edit property values of elements, watch the data context, debug triggers, trace styles and much more. Since March 2011, WPF Inspector is open source and available on CodePlex.</p> <a href="http://wpfinspector.codeplex.com/releases/view/62380">Download WPF Inspector from CodePlex</a> <br/><br/> http://www.wpftutorial.net/Inspector.html Sat, 04 Feb 2012 19:21:28 +01002011-03-23 07:01:43