2009-05-13 7 views
1

Ich versuche, auf eine Schaltfläche in einer XAML-Datei innerhalb eines Codes hinter der Datei meiner MainWindow.xaml zuzugreifen. Ich habe versucht, X: Class in der Datei zu verwenden, aber wenn ich es verwende, funktioniert der Button, aber ich bekomme viele andere Fehler. Deshalb bevorzuge ich diese Methode nicht.WPF-Zugriffssteuerungen in <ResourceDictionary>

Gibt es andere Möglichkeiten zum Zugriff auf Steuerelemente in einer Vorlage mit einem aus der Hauptfenster-Klasse.

der 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> 
+0

Könnten Sie bitte angeben WARUM versuchen Sie, einen Verweis auf eine Schaltfläche in einer Vorlage zu erhalten? Ich mag mich irren, aber in 99,9% ist es eine schlechte Übung, solche Dinge in WPF zu tun. – arconaut

Antwort

0

Es ist möglich, auf den Inhalt eines Datentemplate zuzugreifen. Sie können das Stammelement der Vorlage wie diese:

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

Von dort aus können Sie die VisualTreeHelper verwenden für ein Button-Steuerelement zu suchen.

Wenn Sie nur mit einem Klick auf die Schaltfläche umgehen möchten, ist die Verwendung der RoutedEvents von WPF eine bessere Alternative.

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

Dies wird jeden Knopf klicken, unabhängig von der Quelle. Wenn Sie der Schaltfläche ein Tag oder etwas geben, können Sie das testen, um nur die gewünschten Schaltflächen zu filtern.

0

Sie können einen RoutedCommand angeben, den Sie über CommandBinding zu DataTemplate und zur Schaltfläche hinzufügen können. Auf diese Weise können Sie die Schaltfläche click/command ausführen, zum Beispiel im Code hinter und müssen nicht die Schaltfläche über den VisualTreeHelper finden (oder mein Tipp wäre SomeElement.TryFindResource ("ButtonKey")).

Klar was ich meine oder habe ich missverstanden die Sache, die Sie mit Ihnen Knopf machen wollen?

0

Zuerst erstellen Sie eine .cs-Datei, in der Sie Ihre Befehle registrieren. Dies könnte MyCommandCollection.cs heißen. In dieser Klasse, die Sie definieren und registrieren Sie Ihren RoutedCommand mit:

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

Sie definieren den Befehl in dem Usercontrol oder das Fenster Sie wollen, es zu benutzen innerhalb z.B.

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

Im Code-Behind Ihres UserControl/Window implementieren Sie die Execute/CanExecute Methoden Ihres Befehls.

Auf diese Weise können sie auch in einem Resource, zum Beispiel wie das verwenden können:

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

Vergessen Sie nicht, auch die Namespaces Ihrer „MyCommandCollectionClass.cs“ im Usercontrol/Fenster gestellt und die ResourceDictionary, zum Beispiel:

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

Hoffe, dass dies hilft.

0

Wenn Sie CodeBehind für den Inhalt einer Vorlage benötigen, ist es in der Regel eine gute Idee, den Vorlageninhalt in ein Benutzersteuerelement zu verschieben. (Und es ist oft eine gute Idee, auch wenn Sie keine Codebehind benötigen.)

Diese answer to another question veranschaulicht die Technik. (Die Frage scheint nicht relevant zu sein, aber die Antwort beinhaltete den gleichen Ansatz, den ich hier befürworte. Dieses Beispiel verwendet hierarchische Vorlagen, aber es ist genauso für normale anwendbar.)

Benutzersteuerelemente bieten zwei Vorteile Hier. Erstens helfen sie dabei, übermäßig komplizierte Xaml-Dateien zu vermeiden - es ist einfach für Vorlagen, eine Xaml-Datei zu dominieren, wenn Sie ihre Körper inline lassen, anstatt sie in ihre eigenen Dateien zu trennen. Zweitens können Sie Codebehind leicht verwenden.

Das sagte, stimme ich mit den verschiedenen anderen Antworten hier, die befürworten Vermeidung von Codebehind in erster Linie. (Ich stimme nicht ganz mit ihren spezifischen Lösungen überein - ich benutze den Befehl-basierten Ansatz, aber ich verwende nicht RoutedCommand - ich benutze eine benutzerdefinierte Implementierung von ICommand, die einem Muster folgt, das typischerweise DelegatingCommand oder RelayCommand genannt wird.) Aber selbst dann Ich definiere immer noch Vorlagenkörper als Benutzersteuerelemente, nur um den Xaml zu vereinfachen.