views:

254

answers:

1

I am attempting to create a reusable navigation style Custom Control in WPF, like a navigation bar on a website. It will contain links to all the main Pages in my app. This control can go on top of all my Pages in my NavigationWindow. Giving a nice consistent look and feel across pages, like a website.

My issue is in styling the current page's link differently than the other pages' links, so that you can quickly glance at it and see which page you're on. Since the control is the same on each Page, I need to tell it which page is "active" and have it style that link appropriately.

My first thought was to simply place Is<Page>Active properties on the control, one for each page, and then set the appropriate property to true on the page. (Or I could use one property that accepts an Enum value instead of having many properties, either way)

Example:

<local:Header IsHomePageActive="True" />

Now in the control template for my Header Custom Control, I can create a DataTrigger that watches this property:

<Style.Triggers>
  <DataTrigger Binding="{Binding RelativeSource FindAncestor, AncestorType={x:Type local:Header}}, Path=IsHomePageActive}" Value="true">
    <Setter ... />
    <Setter ... />
    <Setter ... />
  </DataTrigger>
</Style>

After all that background, here's my question. This works, but I'm going to have to duplicate that DataTrigger, and all the Setters in it, for every single Page I have, because the Trigger has to directly reference the "IsHomePageActive" property which only applies to the one link. So I need a different Style for every link, even though the actual STYLE its describing is exactly the same (by which I mean, the Setters are the same). The only difference is what property the trigger is watching.

Is there some way to do this (or something with the same end result) without ending up with hundreds of lines of duplicated XAML?

+1  A: 

How about using a master/detail pattern () with a listbox(say) as the master and your pages as the details.

Then specify your style for the selected item in the list.

The page will change when a different list item is selected and it will look different to the other items.

if you have a dependency property such as List Pages where Page inherits from UserControl and has a string Title you can use

        <ListBox
                 ItemsSource="{Binding Pages}"
                 IsSynchronizedWithCurrentItem="true">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Title}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <ScrollViewer VerticalScrollBarVisibility="Auto"
                      Content="{Binding Pages/}" />

Then just set style for the selected item on the listbox

Gabe