Skip to content

Commit 6a26c36

Browse files
authored
Merge pull request #9251 from syncfusion-content/1025274-Staging
1025274: Updated the WPF to Blazor migration
2 parents 1f37169 + f0a59d6 commit 6a26c36

1 file changed

Lines changed: 12 additions & 12 deletions

File tree

blazor/common/migration/wpf-blazor-migration.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ Data binding is a fundamental concept in both WPF and Blazor, but the implementa
163163

164164
In WPF, the `DataContext` property is a powerful mechanism that enables declarative data binding. You set the `DataContext` to a view model instance that typically implements `INotifyPropertyChanged`, and XAML bindings automatically resolve against this object. This allows UI elements to automatically update when the underlying data changes.
165165

166-
When the data source implements `INotifyCollectionChanged` (such as `ObservableCollection<T>`), the `SfDataGrid` control automatically refreshes the UI when items are added, removed, or when the list is cleared. However, when using a standard `List<T>`, the grid will not automatically refresh when the collection is modified.
166+
When the data source implements [INotifyCollectionChanged](https://learn.microsoft.com/en-us/dotnet/api/system.collections.specialized.inotifycollectionchanged?view=net-10.0) (such as [ObservableCollection<T>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=net-10.0)), the [SfDataGrid](https://www.syncfusion.com/wpf-controls/datagrid) control automatically refreshes the UI when items are added, removed, or when the list is cleared. However, when using a standard `List<T>`, the grid will not automatically refresh when the collection is modified.
167167

168168
{% tabs %}
169169
{% highlight c# tabtitle="MainWindow.xaml.cs" %}
@@ -230,7 +230,7 @@ public class Order
230230

231231
In Blazor, data flows through component parameters and the `@bind` directive. Instead of a global `DataContext`, each component explicitly defines its data dependencies through parameters. This approach provides more explicit data flow, better component composition, and type-safe binding.
232232

233-
The [Blazor DataGrid](https://www.syncfusion.com/blazor-components/blazor-datagrid) supports binding to any `IEnumerable` collection such as `List<T>`, `ObservableCollection<T>`, collections of `ExpandoObject`, `DynamicObject`, or `DataTable`, directly to the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_DataSource) property of the Grid. When using `ObservableCollection<T>`, the component automatically reflects changes made externally. For standard `List<T>`, call the [Refresh](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Refresh_System_Boolean_) method to reflect externally made changes to avoid tracking changes for performance considerations.
233+
The [Blazor DataGrid](https://www.syncfusion.com/blazor-components/blazor-datagrid) supports binding to any `IEnumerable` collection such as `List<T>`, [ObservableCollection<T>](https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=net-10.0), collections of [ExpandoObject](https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?view=net-10.0), [DynamicObject](https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.dynamicobject?view=net-10.0), or `DataTable`, directly to the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_DataSource) property of the Grid. When using `ObservableCollection<T>`, the component automatically reflects changes made externally. For standard `List<T>`, call the [Refresh](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Refresh_System_Boolean_) method to reflect externally made changes to avoid tracking changes for performance considerations.
234234

235235
{% tabs %}
236236
{% highlight razor tabtitle="Orders.razor" %}
@@ -272,14 +272,14 @@ The [Blazor DataGrid](https://www.syncfusion.com/blazor-components/blazor-datagr
272272
{% endhighlight %}
273273
{% endtabs %}
274274

275-
**Key differences in data binding:**
275+
**Key differences in data binding**
276276

277277
| Aspect | WPF DataContext | Blazor Parameters |
278278
|---|---|---|
279279
| Scope | Global to window/control hierarchy | Explicit per component |
280280
| Binding declaration | `{Binding PropertyName}` in XAML | `@PropertyName` or `@bind` in Razor |
281281
| Property changes | `INotifyPropertyChanged` triggers UI updates | Component state changes trigger re-renders |
282-
| Collection type | `ObservableCollection<T>` for automatic notifications | `List<T>` or `ObservableCollection<T>` (for `ObservableCollection<T>`, automatic notifications; for `List<T>`, call `Refresh()` method) |
282+
| Collection type | `ObservableCollection<T>` for automatic notifications | `List<T>` or `ObservableCollection<T>` (for `ObservableCollection<T>`, automatic notifications; for `List<T>`, call [Refresh()](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.SfGrid-1.html#Syncfusion_Blazor_Grids_SfGrid_1_Refresh_System_Boolean_) method) |
283283
| Type safety | Resolved at runtime | Type-safe at compile time |
284284
| Two-way binding | `{Binding PropertyName, Mode=TwoWay}` | `@bind-Value="@PropertyName"` |
285285
| Update notification | Automatic via `PropertyChanged` event | Automatic for `ObservableCollection<T>` or manual via `Refresh()` or re-assignment for `List<T>` |
@@ -462,7 +462,7 @@ Blazor components render as standard HTML and CSS in the browser, requiring a sh
462462
{% endhighlight %}
463463
{% endtabs %}
464464

465-
**Key differences:**
465+
**Key differences**
466466

467467
| Aspect | WPF | Blazor |
468468
|---|---|---|
@@ -473,7 +473,7 @@ Blazor components render as standard HTML and CSS in the browser, requiring a sh
473473
| Overflow handling | Controlled by layout panels (StackPanel, Grid, DockPanel) | CSS overflow properties |
474474
| Rendering | GPU rendering via native engine | Browser rendering engine (hardware-accelerated) |
475475

476-
**Migration strategy:**
476+
**Migration strategy**
477477

478478
* Replace fixed pixel dimensions with flexible CSS units (percentages, em, rem) where appropriate
479479
* Use CSS Flexbox or CSS Grid in place of WPF layout panels (StackPanel, Grid, DockPanel)
@@ -485,7 +485,7 @@ Blazor components render as standard HTML and CSS in the browser, requiring a sh
485485

486486
**WPF lifecycle**
487487

488-
WPF controls follow a predictable, synchronous lifecycle: `Loaded`, property change notifications via `DependencyProperty`, `DataContextChanged`, and `Unloaded`. Event handling is direct through routed events and delegates, executing synchronously on the UI thread. This ensures tight control over component state but can block the UI if long-running operations aren't handled properly.
488+
WPF controls usually follow a synchronous lifecycle. Events like `Loaded` and `Unloaded` are used to start work, clean up resources, and respond to user actions directly on the UI thread. This approach is straightforward, but long-running tasks can block the interface if they are not handled carefully.
489489

490490
{% tabs %}
491491
{% highlight c# tabtitle="MainWindow.xaml.cs" %}
@@ -523,7 +523,7 @@ public class MainWindow : Window
523523

524524
**Blazor lifecycle**
525525

526-
Blazor components use an asynchronous lifecycle model designed for server-client communication: `OnInitialized` / `OnInitializedAsync`, `OnParametersSet` / `OnParametersSetAsync`, and `OnAfterRender` / `OnAfterRenderAsync`. Event handling is through `EventCallback` delegates, supporting both synchronous and asynchronous operations. This asynchronous model prevents blocking the server-side interactive connection but requires a shift in thinking about component initialization and updates.
526+
Blazor uses an asynchronous lifecycle that fits browser rendering and server communication. Common lifecycle methods include `OnInitializedAsync`, `OnParametersSetAsync`, and `OnAfterRenderAsync`. Event handling is also flexible, so component logic can run synchronously or asynchronously depending on the task.
527527

528528
{% tabs %}
529529
{% highlight razor tabtitle="Sample.razor" %}
@@ -612,26 +612,26 @@ Blazor components use an asynchronous lifecycle model designed for server-client
612612
{% endhighlight %}
613613
{% endtabs %}
614614

615-
**Key differences:**
615+
**Key differences**
616616

617617
| Aspect | WPF | Blazor |
618618
|---|---|---|
619619
| Initialization | Synchronous `Loaded` event | Asynchronous `OnInitializedAsync` |
620620
| Parameter changes | `DependencyProperty` change notifications | `OnParametersSetAsync` |
621621
| Post-render operations | Direct event handler execution | `OnAfterRenderAsync` |
622-
| Event handling | Synchronous routed events and delegates | Direct EventCallback properties (e.g., `OnActionBegin`, `OnActionComplete`) |
622+
| Event handling | Synchronous routed events and delegates | Direct `EventCallback` properties such as `OnActionBegin` and `OnActionComplete` |
623623
| Cleanup | `Unloaded` event | `IAsyncDisposable` interface |
624624
| Rendering model | Immediate, blocking in UI thread | Server-side with SignalR client updates |
625625
| Performance implications | Blocking operations freeze the UI | Async/await prevents server blocking |
626626

627-
**Migration strategy:**
627+
**Migration strategy**
628628

629629
* Convert synchronous event handlers to asynchronous `EventCallback` methods
630630
* Move initialization logic from `Loaded` to `OnInitializedAsync`
631631
* Use `OnParametersSetAsync` for responding to parameter changes instead of `DependencyProperty` handlers
632632
* Leverage `OnAfterRenderAsync` for DOM-dependent logic and JavaScript interop
633633
* Implement `IAsyncDisposable` and use the `@implements` directive for proper resource cleanup
634-
* **Always use `async`/`await`** in event handlers and lifecycle methods to prevent blocking the interactive server connection
634+
* Always use `async`/`await` in event handlers and lifecycle methods to prevent blocking the interactive server connection
635635
* Test thoroughly for race conditions that may occur due to asynchronous re-rendering
636636

637637
## Run the application

0 commit comments

Comments
 (0)