JuHwon
JuHwon

Reputation: 2063

WPF Visibility Resource with Binding

I got a WPF Application using MVVM Light. In one View i got many Controls which are using the same visibility binding. Because i dont like to insert my long binding path to every control. I'd like to use a Resource...

<SomeControl>
  <SomeControl.Resource>
    <Visibility x:Key="myVisibilityResource" >
        <Binding Path="somePath" Converter="BoolToVisibilityConverter"></Binding>
    </Visibility>
  </SomeControl.Resource>
<SomeControl>

With this version i get the Error that Visibility does not support direct content. I would have to write it like this:

<Visibility x:Key="myVisibilityResource" >
    Collapsed
</Visibility>

Any ideas?

Upvotes: 4

Views: 5295

Answers (3)

Joe Sonderegger
Joe Sonderegger

Reputation: 804

Create a style in resources:

<Style TargetType="Control" x:Key="VisibilityStyle">
            <Setter Property="Visibility" 
 Value="{Binding Converter={StaticResource VisibleIfFalse}}"/>
</Style>

Then simply add the reference to the item to hide/show.

<TextBlock Text="123" Style="{StaticResource VisibilityStyle}"/>
<TextBlock Text="123" Style="{StaticResource VisibilityStyle}"/>
<TextBlock Text="123" Style="{StaticResource VisibilityStyle}"/>
<TextBlock Text="123" Style="{StaticResource VisibilityStyle}"/>

This also works for headers of grids...

Upvotes: 1

Andrew
Andrew

Reputation: 905

How about something like this? It's not exactly what you asked for, but you would be copying less code around since you wouldn't have to include the converter every time.

<UserControl>
  <Grid>
    <SomeElement x:Name="Master" Visibility="{Binding somePath, Converter={StaticResource BoolToVisibilityConverter}}" />
    <SomeOtherElement Visibility="{Binding Visibility, ElementName=Master}" />
    <SomeOtherElement Visibility="{Binding Visibility, ElementName=Master}" />
  </Grid>
</UserControl>

Upvotes: 1

Jakob Christensen
Jakob Christensen

Reputation: 14956

If all you want is to be able to write "Visible" or "Collapsed" in your XAML (as in your last example) you can do it by binding to and ObjectDataProvider which is uses Enum.Parse to parse the given text (which can be "Visible", "Collapsed", or "Hidden"):

<Grid xmlns:sys="clr-namespace:System;assembly=mscorlib" >
    <Grid.Resources>
        <ObjectDataProvider x:Key="visibilityProvider"
                MethodName="Parse" 
                ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="Visibility" />
                <sys:String>Visible</sys:String>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Grid.Resources>

    <Button x:Name="button1" Visibility="{Binding Source={StaticResource visibilityProvider}}" />

</Grid>

In the above code I am using an ObjectDataProvider to return a Visibility enumeration. The ObjectDataProvider calls Enum.Parse when binding. The button's Visibility property binds to the ObjectDataProvider. The MethodParameters property specifies the parameters for Enum.Parse.

Unfortunately there is no way to bind MethodParameters directly to an underlying ViewModel. If you want to do this, I guess you could write your own ObjectDataProvider or you could use your own class/method instead of Enum.Parse which returns the correct Visibility value.

Upvotes: 2

Related Questions