0

I am trying to bind a bool value to checkboxes in a GridViewColumn, but it doesn't work. I even tried just returning false, but the checkboxes still look enabled. It only works if I type "False" into the xaml.

The binded property is:

public bool HasPermissions
{
    get { return this.UserPrivileges == UserPrivileges.FullAccess; }
}

Current value of this.UserPrivileges is not UserPrivileges.FullAccess.

Xaml code:

<Window x:Class="EffectsWindow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Effects Manager"
        Width="800"
        Height="500"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
    <DockPanel VerticalAlignment="Stretch">
        <DockPanel.Resources>

        <ListView x:Name="EffectsListView"
                  ItemsSource="{Binding AllEffects}">

            <ListView.View>
                <GridView>

                    <GridViewColumn Width="50" Header="Override">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Margin="0"
                                          HorizontalAlignment="Center"
                                          IsEnabled="{Binding HasPermission}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                </GridView>
            </ListView.View>
        </ListView>

    </DockPanel>
</Window>

EDIT: Current property code:

public bool HasPermissions
{
    get { return this.UserPermissions == UserPermissions.FullAccess; }
    set { this.RaisePropertyChanged ( "HasPermissions" ); }
}
Joan Venge
  • 315,713
  • 212
  • 479
  • 689
  • Are you sure that you have implemented INotifyPropertyChanged? – Lav Mar 16 '11 at 20:52
  • Thanks, I didn't implement it. I thought INotifyPropertyChanged is only needed if it's 2 way binding? Like if the value is only defined once, do you still need it? – Joan Venge Mar 16 '11 at 20:57
  • Sorry also meant to say, this property can't be set, only get. – Joan Venge Mar 16 '11 at 20:58
  • Yes you do need that as long as you want to reflect changes in your property out to the UI. Try it. Let us know if it worked or not. – Lav Mar 16 '11 at 20:59
  • In that case what you want to do is in the Setter of UserPriviliges property call OnNotifyPropertyChanged("HasPermissions") – Lav Mar 16 '11 at 21:01
  • Thanks, will try that now. Btw I made this property because I couldn't figure out how to bind to an enum property. Can you also show me how to do that, so I can bind it like: UserPrivileges == UserPrivileges.FullAccess, in the xaml. Or is that a bad practice? – Joan Venge Mar 16 '11 at 21:04
  • I added the new property to the question, is this how you meant? – Joan Venge Mar 16 '11 at 21:06
  • Also not sure if it matters but the same checkboxes' IsChecked property is also data binded. Does that matter? – Joan Venge Mar 16 '11 at 21:11

1 Answers1

1

Think about the problem in your updated property: that property has no backing field, its getter returns the result of comparing a different property with UserPermissions.FullAccess. Therefore it can never be set.

The thing to focus on is, when does the UI need to be notified that the value returned by HasPermissions has changed? Well, when can that value change? When the value of this.UserPermissions changes, right?

Assuming this.UserPermissions is itself a property with a setter, its setter is the place to call RaisePropertyChanged("HasPermissions"). That will tell the UI that, even if it doesn't bind to UserPermissions directly, the property it does bind to must be re-evaluated.

Update: Regarding your comment, IsChecked is indeed the CheckBox property you should bind HasPermissions to if you want the box's checked state to indicate that the user has permission.

Update the 2nd: It sounds like you want to access a property of the Window's DataContext from a visual child (the ListBox). You can use a RelativeSource binding to achieve that, like so:

<CheckBox Margin="0"
          HorizontalAlignment="Center"
          IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.HasPermission}"/>

That somewhat clunky notation will find the nearest parent element to the CheckBox in the visual tree that is of type Window, and bind to its DataContext property to find HasPermission.

Dan J
  • 16,319
  • 7
  • 50
  • 82
  • Thanks, the IsChecked actually represent whether the effect is active or not which uses another binding, but I want some people to be able to modify these values, not everyone. That's why I use IsEnabled too. I tried what you said, but still the checkboxes are enabled, but the HasPermission property returns False. Also I set UserPermissions in the constructor of this object. Does that matter? – Joan Venge Mar 16 '11 at 21:19
  • Sorry I made a mistake. It's confusing. I have a VM class for the whole window, and this VM class called EditorVM has the observable collection which the ListView is binded to. But the property HasPermission is on this EditorVM, not EditorVM.AllEffects. Because the property is global, not per instance of Effect. How do you think I can bind these checkboxes to EditorVM for the IsEnabled property? Does it make sense? – Joan Venge Mar 16 '11 at 21:30
  • Or do you think I have to Bind the ListView to EditorVM and use AllEffects.PropertyName notation for every other binding, to allow me to address the HasPermissions property? – Joan Venge Mar 16 '11 at 21:33
  • @Joan Venge If I understand you correctly, it sounds like you want to access a property of the Window's DataContext from a visual child (the ListBox). See my updated answer. – Dan J Mar 16 '11 at 21:45
  • Thanks, since the problem was unique enough I made another question about this specifically. Hope this gives you more detail about it: http://stackoverflow.com/questions/5332213/how-to-bind-to-2-different-members-in-a-class-in-wpf – Joan Venge Mar 16 '11 at 21:47