wpf-devexpress-dot-mvvm-dot-ui-63f6607b.md
Allows you to bind read-only dependency and attached properties to a ViewModel’s properties.
Namespace : DevExpress.Mvvm.UI
Assembly : DevExpress.Xpf.Core.v25.2.dll
NuGet Package : DevExpress.Wpf.Core
public class ReadOnlyDependencyPropertyBindingBehavior :
Behavior<DependencyObject>
Public Class ReadOnlyDependencyPropertyBindingBehavior
Inherits Behavior(Of DependencyObject)
Specify the following properties to use ReadOnlyDependencyPropertyBindingBehavior :
BindingGets or sets a binding that should be applied to the specified property. This is a dependency property.PropertyGets or sets the bound property’s name. This is a dependency property.DependencyPropertyGets or sets the bound property. This is a dependency property.
Customization properties:
CommandGets or sets the command that the ReadOnlyDependencyPropertyBindingBehavior should execute when the bound property’s value is changed (specified in the Property or DependencyProperty). This is a dependency property.IsEnabledGets or sets whether a bound ViewModel’s property should be updated. This is a dependency property.
Follow the steps below to bind a read-only dependency property to a ViewModel’s property:
Attach the behavior to a target control and choose one of the following options:
Use the behavior’s Binding property to specify a binding to the target ViewModel’s property.
The following code sample binds the TreeView.SelectedItem read-only property to the ViewModel’s SelectedMenuItem property:
<UserControl x:Class="DXSample.Views.MainView"
<!-- ... -->
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
<!-- ... -->
xmlns:ViewModels="clr-namespace:DXSample.ViewModels"
<!-- ... -->
<UserControl.DataContext>
<ViewModels:MainViewModel />
</UserControl.DataContext>
<DockPanel>
<TreeView Name="view" ItemsSource="{Binding Menu}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type ViewModels:MenuItemViewModel}" ItemsSource="{Binding Items}">
<TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:ReadOnlyDependencyPropertyBindingBehavior Binding="{Binding SelectedMenuItem, Mode=OneWayToSource}"
DependencyProperty="{x:Static TreeView.SelectedItemProperty}" />
</dxmvvm:Interaction.Behaviors>
</TreeView>
</DockPanel>
</UserControl>
using System.Collections.ObjectModel;
using System.Windows;
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
// ...
public class MainViewModel : ViewModelBase {
public MenuItemViewModel SelectedMenuItem {
get { return GetProperty(() => SelectedMenuItem); }
set { SetProperty(() => SelectedMenuItem, value); }
}
[Command]
public void Open() {
// ...
}
// ...
}
Imports System.Collections.ObjectModel
Imports System.Windows
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.DataAnnotations
' ...
Public Class MainViewModel
Inherits ViewModelBase
Public Property SelectedMenuItem As MenuItemViewModel
Get
Return GetProperty(Function() Me.SelectedMenuItem)
End Get
Set(ByVal value As MenuItemViewModel)
SetProperty(Function() SelectedMenuItem, value)
End Set
End Property
<Command>
Public Sub Open()
' ...
End Sub
' ...
End Class
To pass validation data from the GridControl to a view model, use the ReadOnlyDependencyPropertyBindingBehavior to bind the view’s HasErrors property to a view model property. Set the view’s ErrorsWatchMode property to Cells.
<dx:ThemedWindow x:Class="DXSample.MainWindow"
Title="{DXBinding '`GridControl has errors: ` + HasErrors'}">
<dx:ThemedWindow.DataContext>
<local:MainViewModel />
</dx:ThemedWindow.DataContext>
<DockPanel>
<dxg:GridControl AutoGenerateColumns="AddNew"
ItemsSource="{Binding TaskList}">
<dxg:GridControl.View>
<dxg:TableView ErrorsWatchMode="Cells"
InvalidRowExceptionCommand="{Binding InvalidRowCommand}"
ValidateRowCommand="{Binding ValidateRowCommand}">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:ReadOnlyDependencyPropertyBindingBehavior Property="HasErrors"
Binding="{Binding HasErrors, UpdateSourceTrigger=PropertyChanged}" />
</dxmvvm:Interaction.Behaviors>
</dxg:TableView>
</dxg:GridControl.View>
</dxg:GridControl>
</DockPanel>
</dx:ThemedWindow>
public class MainViewModel : ViewModelBase {
public bool HasErrors {
get { return GetValue<bool>(); }
set { SetValue(value); }
}
public ObservableCollection<Task> TaskList { get; }
public MainViewModel() {
TaskList = new ObservableCollection<Task> {
new Task() {
TaskName = "Complete Project A",
StartDate = new DateTime(2009, 7, 17),
EndDate = new DateTime(2009, 7, 10)
},
new Task() {
TaskName = "Test Website",
StartDate = new DateTime(2009, 7, 10),
EndDate = new DateTime(2009, 7, 12)
},
new Task() {
TaskName = string.Empty,
StartDate = new DateTime(2009, 7, 4),
EndDate = new DateTime(2009, 7, 6)
}
};
}
[Command]
public void ValidateRow(RowValidationArgs args) {
args.Result = GetValidationErrorInfo((Task)args.Item);
}
static ValidationErrorInfo GetValidationErrorInfo(Task task) {
if (task.StartDate > task.EndDate)
return new ValidationErrorInfo("Start Date must be less than End Date");
if (string.IsNullOrEmpty(task.TaskName))
return new ValidationErrorInfo("Enter a task name");
return null;
}
[Command]
public void InvalidRow(InvalidRowExceptionArgs args) {
args.ExceptionMode = ExceptionMode.NoAction;
}
}
Public Class MainViewModel
Inherits ViewModelBase
Public Property HasErrors As Boolean
Get
Return GetValue(Of Boolean)()
End Get
Set(ByVal value As Boolean)
SetValue(value)
End Set
End Property
Public ReadOnly Property TaskList As ObservableCollection(Of Task)
Public Sub New()
TaskList = New ObservableCollection(Of Task) From {New Task() With {.TaskName = "Complete Project A", .StartDate = New DateTime(2009, 7, 17), .EndDate = New DateTime(2009, 7, 10)}, New Task() With {.TaskName = "Test Website", .StartDate = New DateTime(2009, 7, 10), .EndDate = New DateTime(2009, 7, 12)}, New Task() With {.TaskName = String.Empty, .StartDate = New DateTime(2009, 7, 4), .EndDate = New DateTime(2009, 7, 6)}}
End Sub
<Command>
Public Sub ValidateRow(ByVal args As RowValidationArgs)
args.Result = GetValidationErrorInfo(CType(args.Item, Task))
End Sub
Private Shared Function GetValidationErrorInfo(ByVal task As Task) As ValidationErrorInfo
If task.StartDate > task.EndDate Then Return New ValidationErrorInfo("Start Date must be less than End Date")
If String.IsNullOrEmpty(task.TaskName) Then Return New ValidationErrorInfo("Enter a task name")
Return Nothing
End Function
<Command>
Public Sub InvalidRow(ByVal args As InvalidRowExceptionArgs)
args.ExceptionMode = ExceptionMode.NoAction
End Sub
End Class
Object DispatcherObject DependencyObject Freezable Animatable DevExpress.Mvvm.UI.Interactivity.AttachableObjectBase DevExpress.Mvvm.UI.Interactivity.Behavior DevExpress.Mvvm.UI.Interactivity.Behavior<DependencyObject> ReadOnlyDependencyPropertyBindingBehavior
See Also