2012-03-27 7 views
1

Ich bin neu in WPF-Datenbindung/style/templates ... Ich versuche, einen Satz von Eigenschaftswerte auf Schaltflächen mithilfe eines Style anzuwenden. Der Stil bindet an Felder einer Klasse. Wie Sie sehen, funktioniert das für die BackColor-Eigenschaft. Aber wenn ich versuche, den Text eines Textblocks zu setzen, funktioniert es nicht (und auch kein Bindungsfehler). Mein oberstes Ziel ist es, auch ein Bild als Inhalt festlegen zu können.Wie Bindung in einem WPF DataTemplate, das in einem Style ist

Wenn ich kein DataTemplate verwende und SetterProperty = "Content" anstelle von "ContentTemplate" verwende, funktioniert es für eine Schaltfläche, aber wenn ich eine zweite Schaltfläche hinzufüge, gibt es mir einen Laufzeitfehler "Angegebenes Element ist bereits die logisches Kind eines anderen Elements. Trennen Sie es zuerst. "

Was fehlt mir hier? Was ich in put „TextBlock- Text =“ ???“

btw. Ich möchte den Stil zu einem globalen Rahmen bewegen, wenn es funktioniert, so will ich nichts verwenden, die zu MyClass

ausdrücklich auf
<Window.Resources> 
    <Style TargetType="Button" x:Key="MyStyle"> 
     <Setter Property="Background" Value="{Binding BackColor}"/> 
     <Setter Property="ContentTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock Text="XYZ-"/> 
         <TextBlock Text="{Binding Text}"/> 
        </StackPanel>       
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 
<StackPanel Orientation="Horizontal" Height="30"> 
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action1}"/> 
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action1}"/> 
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action2}"/> 
    <Button Style="{StaticResource MyStyle}" DataContext="{Binding Action2}"/> 
</StackPanel> 

und

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = this; 

     Action1 = new MyClass() { Text = "ACTION1", BackColor = new SolidColorBrush(Colors.Red) }; 
     Action2 = new MyClass() { Text = "ACTION2", BackColor = new SolidColorBrush(Colors.Green) }; 
    } 
    public MyClass Action1{get; private set;} 
    public MyClass Action2{get; private set;} 
} 

public class MyClass 
{ 
    public string Text { get; set; } 
    public Brush BackColor { get; set; } 
} 

Antwort

5

In Ihrer ursprünglichen Frage, benötigt man

<Setter Property="Background" Value="{Binding BackColor}"/> 
<Setter Property="Content" Value="{Binding Text}"/> 

Jetzt müssen Sie verwenden eine relative Quelle

<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
      AncestorType=Button}, Path=DataContext.Text}"/> 

Bindung jedoch können Sie besser dran sein, ein Itemscontrol mit als

XAML

<Page.Resources> 
    <DataTemplate x:Key="ItemTemplate" DataType="{x:Type Samples:MyClass}"> 
     <Button Background="{Binding BackColor}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="XYZ-"/> 
       <TextBlock Text="{Binding Text}"/> 
      </StackPanel> 
     </Button> 
    </DataTemplate> 
    <ItemsPanelTemplate x:Key="ItemsPanelTemplate"> 
     <StackPanel Orientation="Horizontal"/> 
    </ItemsPanelTemplate> 
</Page.Resources> 
<Page.DataContext> 
    <Samples:DataTemplateItemsControlViewModel/> 
</Page.DataContext> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 
    <ItemsControl 
     ItemsSource="{Binding Items}" 
     ItemsPanel="{StaticResource ItemsPanelTemplate}" 
     ItemTemplate="{StaticResource ItemTemplate}"/> 
</Grid> 

C#

public class DataTemplateItemsControlViewModel 
{ 
    public DataTemplateItemsControlViewModel() 
    { 
     Items = 
      new Collection<MyClass> 
       { 
        new MyClass 
         { 
          Text = "ACTION1", 
          BackColor = new SolidColorBrush(Colors.Red) 
         }, 
        new MyClass 
         { 
          Text = "ACTION2", 
          BackColor = new SolidColorBrush(Colors.Blue) 
         }, 
        new MyClass 
         { 
          Text = "ACTION3", 
          BackColor = new SolidColorBrush(Colors.Green) 
         }, 
        new MyClass 
         { 
          Text = "ACTION4", 
          BackColor = new SolidColorBrush(Colors.Yellow) 
         }, 
       }; 
    } 

    public IList<MyClass> Items { get; private set; } 
} 
+0

Dank für Ihre Antwort folgt. Ja, das funktioniert, aber ich muss mehr sichtbare Objekte unter dem Inhalt haben. Ich habe mein Codebeispiel bearbeitet, um dies zu verdeutlichen. – Night94

+0

hat meine aktualisierte Antwort Hilfe? – Phil

+0

nein. Die Verwendung der relativen Quellbindung führt zu den gleichen Ergebnissen wie mein Code oben. Es funktioniert, wenn ich den Stil auf eine Schaltfläche anwende, aber mit mehreren Schaltflächen bekomme ich immer noch die gleiche Ausnahme: "Angegebenes Element ist bereits das logische Kind eines anderen Elements. Trennen Sie es zuerst." – Night94

Verwandte Themen