views:

9

answers:

1

I ran in to the unique situation today where I needed to bind the Visible property of a button in a DataGridRow to be based on both a property of the bound object and of the model backing it.

XAML:

<t:DataGrid ItemsSource="{Binding Items}">
    <t:DataGrid.Columns>
        <t:DataGridTemplateColumn>
            <t:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Visibility="IsEditable OR IsAdmin"/>
                </DataTemplate>
            </t:DataGridTemplateColumn.CellTemplate>
        </t:DataGridTemplateColumn>
    </t:DataGrid.Columns>
</t:DataGrid>

Model:

class TheModel
{
    public ObservableCollection<Whatever> Items { get; set; }
    public bool IsAdmin { get; set; }
}

Class:

class Whatever
{
    public bool IsEditable { get; set; }
}

This stumped me. The only concept that I could think might work would be somehow passing the bound object and either the entire model or just the IsAdmin property to a static method on a converter or something. Any ideas?

+1  A: 

Firstly, you cannot directly use a Boolean for Visibility. You need to use the BooleanToVisibilityConverter.

Secondly, about the OR, you have different options:

  1. Create a readonly property IsEditableOrAdmin in Whatever which returns the value you want. Drawback: Your Whatever will need a back-reference to TheModel.

  2. Use a MultiBinding and write an IMultiValueConverter. Then, pass both values in the MultiBinding. Since TheModel is no longer in the DataContext scope at that point, you could use the ElementName property of the Binding to refer to a UI element where TheModel is still accessible.

    Example (untested):

    <SomeElementOutsideYourDataGrid Tag="{Binding TheModel}" />
    ...
        <Button>
            <Button.Visibility>
                <MultiBinding Converter="{StaticResource yourMultiValueConverter}">
                    <Binding Path="IsEditable" />
                    <Binding ElementName="SomeElementOutsideYourDataGrid" Path="Tag.IsAdmin"/>
                </MultiBinding>
            </Button.Visibility>
        </Button>
    
  3. Use a more powerful binding framework such as PyBinding.

Heinzi
The example was a highly simplified version of the actual implementation which was already using a custom converter. Changing to an `IMultiValueConverter` and passing both did the trick. Thanks!
Jake Wharton