Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ReadOnly Dependency Properties using MVVM

I've recently overridden the DevXpress WPF grid to give myself a SelectedObject property that I can access from my loosely bound ViewModel.

I've made a SelectedObject dependency property and have it bound OneWayToSource in my XAML.

Everthing works fine, but if I try to make it ReadOnly (for completeness) I get a compile error and says I can't bind to a ReadOnly property. The code below compiles, I've included (but rem'd out) the bits I've been trying in my attempts to get the property ReadOnly.

Can anyone assist please?

The Dependency Property of my overridden control looks like:

  //public static readonly DependencyPropertyKey SelectedRowKey = DependencyProperty.RegisterReadOnly("SelectedObject", typeof(object), typeof(MyGrid), new PropertyMetadata(null));
//public static readonly DependencyProperty SelectedObjectProperty = SelectedRowKey.DependencyProperty;

public readonly static DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(MyGrid), new PropertyMetadata(null));

public object SelectedObject
{
    get
    {

        return GetValue(SelectedObjectProperty);
    }
    set
    {
        throw new NotImplementedException();
    }
}

The XAML is:

 <StackPanel>
  <devxgrid:MyGrid AutoPopulateColumns="True" DataSource="{Binding Animals}" SelectedObject="{Binding MyObject, Mode=OneWayToSource}" Width="300" Height="300">
    <devxgrid:MyGrid.View>
        <MyGrid:TableView AllowEditing="False" Name="GridView" AutoWidth="True" />
    </devxgrid:MyGrid.View>
 </devxgrid:MyGrid>
</StackPanel>
like image 601
Andy Clarke Avatar asked Nov 17 '09 14:11

Andy Clarke


2 Answers

You're trying to set the SelectedObject property in the XAML. If it's read-only, how can you set it?

Edit: sorry, my bad. Just realized what you're trying to do, and you're right that it should work. However, WPF doesn't support this scenario, at least in 3.5.

Edit 2: Just checked in .NET 4 and same story.

By the way, if you're stuck with someone else's readonly DP that you're trying to "push" into a VM, you can use an attached behavior to workaround this. For example, suppose you want your VM to be aware of the ActualWidth and ActualHeight properties of your view. You can write a SizeWatcherBehavior that attaches to the FrameworkElement and listens for size changes. When detected, those size changes are pushed to read/write attached properties that your VM can bind to:

<Grid local:SizeWatcherBehavior.Watch="True"
    local:SizeWatcherBehavior.Width="{Binding WidthOnVM, Mode=OneWayToSource}"
    local:SizeWatcherBehavior.Height="{Binding HeightOnVM, Mode=OneWayToSource}"/>
like image 136
Kent Boogaart Avatar answered Sep 22 '22 12:09

Kent Boogaart


I'm a little late to this question considering it was asked almost 2 years ago :)

I made a solution to dynamically be able to push read-only dependency properties to the source called PushBinding which I blogged about here. In your case it would look like this

<devxgrid:MyGrid AutoPopulateColumns="True"
                 DataSource="{Binding Animals}"
                 Width="300"
                 Height="300">
    <pb:PushBindingManager.PushBindings>
        <pb:PushBinding TargetProperty="SelectedObject" Path="MyObject"/> 
    </pb:PushBindingManager.PushBindings> 
    <!--...-->
</devxgrid:MyGrid> 

PushBinding works by using two Dependency Properties, Listener and Mirror. Listener is bound OneWay to the TargetProperty and in the PropertyChangedCallback it updates the Mirror property which is bound OneWayToSource to whatever was specified in the Binding.

Demo Project can be Downloaded Here.
It contains source code and short sample usage, or visit my WPF blog if you're interested in the implementation details.

like image 37
Fredrik Hedblad Avatar answered Sep 23 '22 12:09

Fredrik Hedblad