NoOne
NoOne

Reputation: 4091

WPF Bind to resource instance

I have a ContextMenu defined in XAML and I modify it in code:

ContextMenu EditContextMenu;
EditContextMenu  = (ContextMenu)this.FindResource("EditContextMenu");
//Modify it here...

Then, I need to set it as a ContextMenu for all TextBoxes, DatePickers, etc in a XAML theme file using data binding. I've tried adding a property to the main window :

    public ContextMenu sosEditContextMenu
    {
        get
        {
            return EditContextMenu;
        }
    }

...and binding it like this (the folowing is from a theme file with 'FTWin' being the Name of my main window where the sosEditContextMenu property is defined):

<Style TargetType="{x:Type TextBox}">
    <Setter Property="ContextMenu" Value="{Binding Source=FTWin, Path=sosEditContextMenu}"/>
</Style>

...but it doesn't work. I've tried various things and I either got Exceptions about resources not being found or nothing happened.

Is what I'm trying to do possible and, if yes, what am I doing wrong? I don't know if setting the DataContext of an object could help, but setting it for all TextBoxes by code is not so nice right?

Upvotes: 0

Views: 1667

Answers (1)

Andy
Andy

Reputation: 6466

Put the menu that you defined in xaml in a resource dictionary that can be seen from the textbox and instead of using a binding just use StaticResource to link it in your style.

<Window x:Class="ContextMenu.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>

        <!-- The XAML defined context menu, note the x:Key -->
        <ContextMenu x:Key="EditContextMenu">
            <ContextMenu.Items>
                <MenuItem Header="test"/>
            </ContextMenu.Items>
        </ContextMenu>

        <!-- This sets the context menu on all text boxes for this window .-->
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="ContextMenu" Value="{StaticResource EditContextMenu}"/>
        </Style>        
    </Window.Resources>

    <Grid>

        <!-- no context menu needs to be defined here, it's in the sytle.-->
        <TextBox />
    </Grid>
</Window>

You can still change it in code behind by looking for the resource

public MainWindow()
{
    InitializeComponent();

    System.Windows.Controls.ContextMenu editContextMenu = (System.Windows.Controls.ContextMenu)FindResource("EditContextMenu");
    editContextMenu.Items.Add(new MenuItem() { Header = "new item" });
}

Upvotes: 2

Related Questions