# BindableBase | WPF Controls | DevExpress Documentation

The [BindableBase](/CoreLibraries/DevExpress.Mvvm.BindableBase) class implements the **INotifyPropertyChanged** interface and provides the API to declare bindable property with minimum coding.

## Bindable Properties

To declare bindable properties, do the following:

- inherit your ViewModel from the [BindableBase](/CoreLibraries/DevExpress.Mvvm.BindableBase) class;
- use the **GetValue** and **SetValue** methods in property getters and setters.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
    public string FirstName {
        get { return GetValue&lt;string&gt;(nameof(FirstName)); } 
        set { SetValue(value, nameof(FirstName)); }
    }
}
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName() As String
        Get
            Return GetValue(Of String)(NameOf(FirstName))
        End Get
        Set(ByVal value As String)
            SetValue(value, NameOf(FirstName))
        End Set
    End Property
End Class
</code></pre></section>

The [BindableBase](/CoreLibraries/DevExpress.Mvvm.BindableBase) class exposes the **GetValue** and **SetValue** overloads that use the [CallerMemberNameAttribute](https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.callermembernameattribute). You do not have to pass property name to these methods’ parameter. This simplifies the bindable property declaration:

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-1_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
    public string FirstName {
        get { return GetValue&lt;string&gt;(); } 
        set { SetValue(value); }
    }
}
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-1_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName() As String
        Get
            Return GetValue(Of String)()
        End Get
        Set(ByVal value As String)
            SetValue(value)
        End Set
    End Property
End Class
</code></pre></section>

Note

The [CallerMemberNameAttribute](https://learn.microsoft.com/dotnet/api/system.runtime.compilerservices.callermembernameattribute) is available in .NET Framework 4.5 and above. 

The BindableBase in .NET Framework 4.0 section describes how to use the **BindableBase** View Model in .NET 4.0.

Property values are stored in an internal dictionary:

- the **GetValue** method uses this dictionary to get a property value;
- the **SetValue** method uses the property name as a key to store a property value in the dictionary.

The **SetValue** method returns **True** or **False** values that indicate whether a property has been changed. If you set the same value to the property, the **SetValue** method returns **False** and change notifications are not sent. 

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-2_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
    public string FirstName {
        get { return GetValue&lt;string&gt;(); }
        set {
            if (SetValue(value))
                NotifyFullNameChanged();
            else MessageBox.Show(&quot;Could not change value!&quot;);
        }
    }
}
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-2_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName() As String
        Get
            Return GetValue(Of String)()
        End Get
        Set(ByVal value As String)
            If Not SetValue(value) Then
                NotifyFullNameChanged()
            Else MessageBox.Show(&quot;Could not change value!&quot;)
            End If
        End Set
    End Property
End Class
</code></pre></section>

Note

The simplified property declaration uses a dictionary to store property values. As a result, application performance can decrease when properties are frequently accessed or updated. To avoid this, you can use properties with backing fields.

## Run Custom Code When Property Value Changed

The **SetValue** method has overloads that take a callback method as a parameter. This callback is invoked after a property value has been changed.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
        public string FirstName {
            get { return GetValue&lt;string&gt;(); }
            set { SetValue(value, changedCallback: OnFirstNameChanged); }
        }
        void OnFirstNameChanged() {
            //...
        }
    }
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName() As String
        Get
            Return GetValue(Of String)()
        End Get
        Set(ByVal value As String)
            SetValue(value, changedCallback:= AddressOf OnFirstNameChanged)
        End Set
    End Property
    Sub OnFirstNameChanged()
        &#39;...
    End Sub
End Class
</code></pre></section>

## Manually Raise INotifyPropertyChanged.PropertyChanged

If you need to raise the **INotifyPropertyChanged.PropertyChanged** event for a specific property, use the **RaisePropertyChanged/RaisePropertiesChanged** method.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-4_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
    public string FirstName {
        get { return GetValue&lt;string&gt;(); }
        set { SetValue(value, changedCallback: NotifyFullNameChanged); }
    }

    public string LastName {
        get { return GetValue&lt;string&gt;(); }
        set { SetValue(value, changedCallback: NotifyFullNameChanged); }
    }

    public string FullName { get { return FirstName + &quot; &quot; + LastName; } }

    void NotifyFullNameChanged() {
        RaisePropertyChanged(nameof(FullName));
    }
}
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-4_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName() As String
        Get
            Return GetValue(Of String)()
        End Get
        Set(ByVal value As String)
            SetValue(value, changedCallback:= AddressOf NotifyFullNameChanged)
        End Set
    End Property

    Public Property LastName() As String
        Get
            Return GetValue(Of String)()
        End Get
        Set(ByVal value As String)
            SetValue(value, changedCallback:= AddressOf NotifyFullNameChanged)
        End Set
    End Property

    Public ReadOnly Property FullName() As String
        Get
            Return FirstName &amp; &quot; &quot; &amp; LastName
        End Get
    End Property

    Private Sub NotifyFullNameChanged()
        RaisePropertyChanged(Function() FullName)
    End Sub
End Class
</code></pre></section>

## Using Properties With Backing Fields

An application’s performance can decrease when a property is frequently accessed or updated because property values are stored in the Dictionary. To improve the application’s performance, store property values in backing fields.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
    string _FirstName;
    public string FirstName {
        get { return _FirstName; }
        set { SetValue(ref _FirstName, value, changedCallback: NotifyFullNameChanged); }
    }
}
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-5_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Private _FirstName As String
    Public Property FirstName() As String
        Get
            Return _FirstName
        End Get
        Set(ByVal value As String)
            SetValue(_FirstName, value, changedCallback:= AddressOf NotifyFullNameChanged)
        End Set
    End Property
End Class
</code></pre></section>

## Serialize Bindable Properties

The `BindableBase` class is marked with the [DataContract](https://learn.microsoft.com/dotnet/api/system.runtime.serialization.datacontractattribute) attribute. As a result, the JSON serializer looks only for members marked with the [DataMember](https://learn.microsoft.com/dotnet/api/system.runtime.serialization.datamemberattribute) attribute:

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-6_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;,&quot;/ (System.Runtime.Serialization)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.runtime.serialization&quot;}" class="lang-csharp">using DevExpress.Mvvm;
using System.Runtime.Serialization;
// ...
public class ViewModel : BindableBase {
    [DataMember]
    public string FirstName {
        get { return GetValue&lt;string&gt;(); } 
        set { SetValue(value); }
    }
}
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-6_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;,&quot;/ (System.Runtime.Serialization)(?:;|$)/&quot;:&quot;https://learn.microsoft.com/dotnet/api/system.runtime.serialization&quot;}" class="lang-vb">Imports DevExpress.Mvvm
Imports System.Runtime.Serialization

Public Class ViewModel
    Inherits BindableBase

    &lt;DataMember&gt;
    Public Property FirstName As String
        Get
            Return GetValue(Of String)()
        End Get
        Set(ByVal value As String)
            SetValue(value)
        End Set
    End Property
End Class
</code></pre></section>

## BindableBase in .NET Framework 4.0

### Bindable Properties

Use the **GetProperty** and **SetProperty** methods to implement bindable properties.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-7_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
        public string FirstName {
            get { return GetProperty(() =&gt; FirstName); }
            set { SetProperty(() =&gt; FirstName, value); }
        }
    }
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-7_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName As String
        Get
            Return GetProperty(Function() FirstName)
        End Get
        Set(value As String)
            SetProperty(Function() FirstName, value)
        End Set
    End Property
End Class
</code></pre></section>

The first parameter of the **GetProperty** and **SetProperty** methods is a lambda expression that returns the property used to identify the target property name. The property names are internally obtained with the static **BindableBase.GetPropertyName&lt;T&gt;** method.

### Run Custom Code When Property Value Changed

The **SetProperty** method returns **True** or **False** values that indicate whether a property was changed. If you set the property to the same value, the **SetProperty** method returns **False** and changing notifications are not sent. The **SetProperty** method has overloads that take a callback method as a parameter. This callback is invoked after the field has been changed.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-8_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
        public string FirstName {
            get { return GetProperty(() =&gt; FirstName); }
            set { SetProperty(() =&gt; FirstName, value, OnFirstNameChanged); }
        }
        void OnFirstNameChanged() {
            //...
        }
    }
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-8_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public Property FirstName As String
        Get
            Return GetProperty(Function() FirstName)
        End Get
        Set(value As String)
            SetProperty(Function() FirstName, value, AddressOf OnFirstNameChanged)
        End Set
    End Property
    Sub OnFirstNameChanged()
        &#39;...
    End Sub
End Class
</code></pre></section>

### Manually Raise INotifyPropertyChanged.PropertyChanged

If you need to raise the **INotifyPropertyChanged.PropertyChanged** event for a specific property, use the **RaisePropertyChanged/RaisePropertiesChanged** method.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-9_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
        public string FullName {
            get { return string.Format(&quot;{0} {1}&quot;, FirstName, LastName); }
        }
        public string FirstName {
            get { return GetProperty(() =&gt; FirstName); }
            set { SetProperty(() =&gt; FirstName, value, OnFirstNameChanged); }
        }
        public string LastName {
            get { return GetProperty(() =&gt; LastName); }
            set {
                if(SetProperty(() =&gt; LastName, value))
                    RaisePropertyChanged(() =&gt; FullName);
            }
        }
        void OnFirstNameChanged() {
            RaisePropertyChanged(() =&gt; FullName);
        }
    }
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-9_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Public ReadOnly Property FullName As String
        Get
            Return String.Format(&quot;{0} {1}&quot;, FirstName, LastName)
        End Get
    End Property
    Public Property FirstName As String
        Get
            Return GetProperty(Function() FirstName)
        End Get
        Set(value As String)
            SetProperty(Function() FirstName, value, AddressOf OnFirstNameChanged)
        End Set
    End Property
    Public Property LastName As String
        Get
            Return GetProperty(Function() LastName)
        End Get
        Set(value As String)
            If SetProperty(Function() LastName, value) Then
                RaisePropertyChanged(Function() FullName)
            End If
        End Set
    End Property
    Sub OnFirstNameChanged()
        RaisePropertyChanged(Function() FullName)
    End Sub
End Class
</code></pre></section>

### Using Properties With Backing Fields

An application performance can decrease when a property is frequently updated (due to the calculation of property names from lambda expressions and storing property values in the Dictionary). To accommodate these scenarios, use storage variables for properties and calculate property names once from the static constructor using the **BindableBase.GetPropertyName&lt;T&gt;** method.

- C#
- VB.NET

<section id="tabpanel_iXgmGzHOm8-10_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-csharp">using DevExpress.Mvvm;

public class ViewModel : BindableBase {
        static string Property1Name;
        static ViewModel() {
            Property1Name = BindableBase.GetPropertyName(() =&gt; new ViewModel().Property1);
        }

        string property1;
        public string Property1 {
            get { return property1; }
            set { SetProperty(ref property1, value, Property1Name); }
        }
    }
</code></pre></section>
<section id="tabpanel_iXgmGzHOm8-10_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;/ (DevExpress.Mvvm)(?:;|$)/&quot;:&quot;/CoreLibraries/DevExpress.Mvvm&quot;}" class="lang-vb">Imports DevExpress.Mvvm

Public Class ViewModel
    Inherits BindableBase
    Shared Property1Name As String
    Shared Sub New()
        Property1Name = BindableBase.GetPropertyName(Function() New ViewModel().Property1)
    End Sub

    Dim _Property1 As String
    Public Property Property1 As String
        Get
            Return _Property1
        End Get
        Set(value As String)
            SetProperty(_Property1, value, Property1Name)
        End Set
    End Property
End Class
</code></pre></section>