WPF Access Controls in <ResourceDictionary>

I am trying to access a button in a .xaml file in a file under my MainWindow.xaml code. I tried to use x: Class in the file, but when I use it the button works, but I get many other errors. so I prefer not to use this method.

Are there any other ways to access controls in a template with a from the mainWindows class.

the code:

<ResourceDictionary xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
                xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
                xmlns:l="clr-namespace:Avalon.Demo" x:Class="Bildbanken.MainWindow">

      

                                                                                                                                                                                              

                        <!-- Taggarnas placering under bilderna (Left/ Top/ Right/ Bottom) -->
                        <Label Content="{Binding Type}" Padding="0,5,7,0" HorizontalAlignment="Right" />
                        <Label Content="{Binding Category}" Padding="7,0,0,0" />
                        <ListBox Name="ArtInfo" ItemsSource="{Binding Articles}" BorderThickness="0" Background="{TemplateBinding Background}">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="115px" />
                                            <ColumnDefinition Width="auto" />
                                        </Grid.ColumnDefinitions>
                                        <TextBlock Grid.Column="0" Text="{Binding Artnr}"></TextBlock>
                                        <Button HorizontalAlignment="Right" Name="testbutton" Grid.Column="1">--</Button>
                                    </Grid>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>

      

+1


a source to share


4 answers


You can access the contents of the data table. You can get the root element of the template like this:

UIElement templateRoot = listbox.ItemTemplate.LoadContent() as UIElement;

      

From there, you use the VisualTreeHelper to find the Button control.



If you just want to handle a button click, using WPF Alternate Routes is a better alternative.

AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));

      

This will capture every button regardless of the source. If you give a button a tag or whatever, you can test that to filter out only the buttons you want.

0


a source


You can specify a RoutedCommand, which you can add via CommandBinding to you DataTemplate and to the button. This way you can handle the button / command click, for example in the code behind and don't need to find the button via the VisualTreeHelper (or my tipp would be SomeElement.TryFindResource ("ButtonKey")).



Clear what I mean, or I didn't understand what you want to do with the button?

0


a source


First, create a .cs file where you register your commands. This could be called MyCommandCollection.cs. In this class, you define and register your RoutedCommand with:

   public static readonly RoutedCommand ButtonPressCommand= new RoutedCommand("ButtonPress", typeof(MyCommandCollection));

      

You define a command in the UserControl or the window you want to use for example.

<UserControl.CommandBindings>
     <CommandBinding Command="Commands:MyCommandCollection.ButtonPressCommand" Execute="Execute_ButtonPressCommand" ... />
</UserControl.CommandBindings>

      

In your UserControl / Window code, you implement the Execute / CanExecute methods of your command.

So you can use it in ResourceDictionary as well, like:

<Button Command="Commands:MyCommandCollection.ButtonPressCommand" />

      

Don't forget to put your "MyCommandCollectionClass.cs" namespaces in UserControl / Window and ResourceDictionary as well, for example:

xmlns:Commands="clr-namespace:MyApp.SomeFolder.Commands"

      

Hope it helps.

0


a source


If you require code for the template content, it is generally a good idea to move the template content to a custom control. (And that's often a good idea, even if you don't need the code.)

This answer to another question illustrates the technique. (The question may sound impractical, but the answer turned out to be related to the same approach that I am advocating here. This example uses hierarchical patterns, but they also apply to regular ones.)

Custom controls offer two benefits here. First, they help avoid overly complex Xaml files. It is easy for templates to dominate the Xaml file if you leave their bodies inline rather than splitting them into their own files. Second, you can use codebehind easily.

However, I agree with other other answers here, in which the attorney avoids codes in the first place. (I don't quite agree with their specific solutions - I am using a team approach, but I am not using RoutedCommand

- I am using a custom implementation ICommand

that follows a pattern usually called DelegatingCommand or RelayCommand.) But even then, I still almost define the bodies of the templates as custom controls, just to simplify Xaml.

0


a source







All Articles