eXPerience
eXPerience

Reputation: 466

WPF Bind c# class to static resource

I have a xaml toolbar:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:logic="clr-namespace:DD.Logic;assembly=DD.Logic">

<ToolBar x:Key="MyToolbar" Height="120">
    <!--File-->
    <GroupBox Header="File" Style="{StaticResource ToolbarGroup}" Margin="5,3,3,3">
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Margin="3" Width="55" Style="{StaticResource ToolBarButtonBaseStyle}"
                    Command="{x:Static ApplicationCommands.New}">
                <Button.Content>
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="4*"/>
                            <RowDefinition Height="1*"/>
                        </Grid.RowDefinitions>
                        <Image Source="Images/GenericDocument.png" Width="45"/>
                        <TextBlock Grid.Row="1" Text="New" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
                    </Grid>
                </Button.Content>
            </Button>
            <StackPanel Orientation="Vertical" Margin="0,2,0,2">
                <Button Margin="1" Padding="2" HorizontalContentAlignment="Left"
                        Style="{StaticResource ToolBarButtonBaseStyle}"
                        Command="{x:Static ApplicationCommands.Open}">
                    <Button.Content>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Image Source="Images/OpenFolder.png" Width="16"/>
                            <TextBlock Margin="3,0,3,0" Text="Open" VerticalAlignment="Center"  Grid.Column="1"/>
                        </Grid>
                    </Button.Content>
                </Button>
                <Button Margin="1" Padding="2" HorizontalContentAlignment="Left"
                        Style="{StaticResource ToolBarButtonBaseStyle}"
                        Command="{x:Static ApplicationCommands.Save}">
                    <Button.Content>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition />
                            </Grid.ColumnDefinitions>
                            <Image Source="Images/Save.png" Width="16"/>
                            <TextBlock Margin="3,0,3,0" Text="Save" VerticalAlignment="Center" Grid.Column="1"/>
                        </Grid>
                    </Button.Content>
                </Button>
                <Button Margin="1" Padding="2" HorizontalContentAlignment="Left"
                        Style="{StaticResource ToolBarButtonBaseStyle}"
                        Command="{x:Static ApplicationCommands.Print}">
                    <Button.Content>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition />
                            </Grid.ColumnDefinitions>
                            <Image Source="Images/Print.png" Width="16"/>
                            <TextBlock Margin="3,0,3,0" Text="Print" VerticalAlignment="Center" Grid.Column="1"/>
                        </Grid>
                    </Button.Content>
                </Button>
            </StackPanel>
        </StackPanel>
    </GroupBox>

    <!--Format-->
    <GroupBox Header="Format" Style="{StaticResource ToolbarGroup}" Margin="3">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid Row="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0">Text font size:</TextBlock>
                <ComboBox VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="1"
                Height="20"
                Width="80"
                IsEditable="True"
                Loaded="{x:Static logic:ApplicationToolbar.RoutedEvent}"
                TextBoxBase.TextChanged="{x:Static logic:ApplicationToolbar.SelectionChangedEvent}"
            />
            </Grid>
            <Grid Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0">Arrows:</TextBlock>
                <ComboBox VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="1"
                          Name ="ArrowsCombobox"
                Height="20"
                Width="80"
                Loaded="{x:Static logic:ApplicationToolbar.ArrowsComboboxLoaded}"
                SelectionChanged="{x:Static logic:ApplicationToolbar.ArrowsComboboxSelectionChanged}"
            />
            </Grid>
        </Grid>
    </GroupBox>
</ToolBar>

Which is show in main window as:

<ContentControl  Content="{StaticResource MyToolbar}"/>

And a class that implements the corresponding commands and evenhandlers:

public class ApplicationToolbar : Control
{
    public static PathFinderType PathFinderType = PathFinderType.Straight;

    public static RoutedEventHandler RoutedEvent = LoadFontSizes;
    public static TextChangedEventHandler SelectionChangedEvent = FontSizeChanged;
    public static RoutedEventHandler ArrowsComboboxLoaded = ArrowsComboboxLoadedHandler;
    public static SelectionChangedEventHandler ArrowsComboboxSelectionChanged = ArrowsComboboxSelectionChangedHandler;

    public static RoutedCommand Group = new RoutedCommand();
    public static RoutedCommand Ungroup = new RoutedCommand();
    //etc
    public static RoutedCommand Redo = new RoutedCommand();
    private readonly IDesignerCommandsReceiver _receiver;

    public ApplicationToolbar()
    {
        var designer = FindChild<DesignerCanvas>(Application.Current.MainWindow, "DesignerCanvas");
        _receiver = new DesignerCommandsReceiver(designer);
        AddCommandBindings();
        AddCommandGestures();
    }
    private void AddCommandBindings()
    {
        CommandBindings.Add(new CommandBinding(ApplicationCommands.New, New_Executed));

        // some more bindings

        CommandBindings.Add(new CommandBinding(Redo, Redo_Executed, Redo_Enabled));
    }
    private static void AddCommandGestures()
    {
        SelectAll.InputGestures.Add(new KeyGesture(Key.A, ModifierKeys.Control));
        Undo.InputGestures.Add(new KeyGesture(Key.Z, ModifierKeys.Control));
        Redo.InputGestures.Add(new KeyGesture(Key.Y, ModifierKeys.Control));
    }
    private void New_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        _receiver.New();
    }        

    // other commands implementations

    private void Redo_Enabled(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = StateSaver.Instance.IsRedoAvailable();
    }

    public static void ArrowsComboboxLoadedHandler(object sender, RoutedEventArgs e)
    {

    }
    private static void ArrowsComboboxSelectionChangedHandler(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
    {

    }

    // other event handlers     
}
public enum PathFinderType
{
    Straight,
    Ambient,
    Polygon
}

How do I bind this class to the xaml presentation? I tried to use ContentPresenter with specified DataContext, but it doesn't work:

<ContentPresenter Content="{StaticResource MyToolbar}" DataContext="{x:Type logic:ApplicationToolbar}"/>

Update The ApplicationToolbar.xaml is now:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:logic="clr-namespace:DD.Logic;assembly=DD.Logic">
<ControlTemplate x:Key="MyToolbar">
    <ToolBar  Height="120">
//similar code
</ToolBar>
</ControlTemplate>

And it's printed out as:

<ContentPresenter>
        <ContentPresenter.Content>
            <logic:ApplicationToolbar />
        </ContentPresenter.Content>
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <Control Template="{StaticResource MyToolbar}" />
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>

Still haven't achieved commands to work <- The issue was solved by putting all commands related code back to designer class. I suppose that CommandBindings are supposed to be added to CommandBindingsCollection of designer object, and not application toolbar.

Upvotes: 1

Views: 1498

Answers (1)

mm8
mm8

Reputation: 169200

Try something like this:

<ContentPresenter>
    <ContentPresenter.Content>
        <logic:ApplicationToolbar />
    </ContentPresenter.Content>
    <ContentPresenter.ContentTemplate>
        <DataTemplate>
            <ContentControl Content="{StaticResource MyToolbar}" />
        </DataTemplate>
    </ContentPresenter.ContentTemplate>
</ContentPresenter>

The Content property of a ContentPresenter is supposed to be set to an instance of the DataContext/ViewModel and the ContentTemplate to a DataTemplate that defines the appearance of this object.

Upvotes: 1

Related Questions