Entwickler-Ecke

WPF / Silverlight - Binding innerhalb DataTemplate funktioniert nicht


C# - Di 13.12.16 15:27
Titel: Binding innerhalb DataTemplate funktioniert nicht
Hey @ll,

ich habe ein kleines Problem mit dem Binden von Daten in einem DataTemplate eines ItemsControls. Ich habe eine ObservableCollection "Templates" die mit Objekten gefüllt ist, die alle INotifyPropertyChanged implementieren. Diese Collection möchte ich an das ItemsControl binden und die einzelnen Items sollen mit dem "TemplateView" Control angezeigt und verändert werden. Das Control selbst funktioniert, wenn ich es außerhalb des ItemsControl teste. Jedoch werden mir in dem ItemsControl nur die default Werte der Templates angezeigt, was definitiv nicht stimmen kann. Auch verändern sich die Templates selbst nicht, wenn ich die TemplatesView ändere. Jede TemplateView ist an ein Template gebunden.

Der DataContext ist selbstverständlich gesetzt. Ich habe die Collection testweise mal 3 Objekten gefüllt. Es werden auch 3 TemplateViews angezeigt, nur eben mit default Werten

Warum funktioniert das Binding innerhalb des DataTemplate nicht?

Hier de XAML Code:

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
            <GroupBox Header="Templates" Padding="5,10">
                <ScrollViewer VerticalScrollBarVisibility="Auto">
                    <ItemsControl ItemsSource="{Binding Templates}" MinWidth="100" >
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <local:TemplateView OriginalTemplate="{Binding}" />
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </ScrollViewer>
            </GroupBox>


Template:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
    public class Template : ModelBase
    {
        public string Name
        {
            get { return GetValue<string>(); }
            set { SetValue(value); }
        }

        public int BlockSize
        {
            get { return GetValue<int>(); }
            set { SetValue(value); }
        }

        public override ModelBase Clone()
        {
            return new DentTemplate
            {
                Name = Name,
                BlockSize = BlockSize,
            };
        }
    }

Die Klasse ModelBase übernimmt hier das Management der Properties und die nötigen NotifyPropertyChanged events. Diese Klasse funktioniert definitiv (wurde schon mehrfach verwendet).

Ausschnitt aus TemplateView:

XML-Daten
1:
2:
3:
4:
5:
6:
            <TextBlock Text="Block Size:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" />

            <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding ElementName=BlockSizeSlider, Path=Value}" Margin="5,0" VerticalAlignment="Center" HorizontalAlignment="Right" />

            <Slider x:Name="BlockSizeSlider" Grid.Row="2" Grid.Column="2" VerticalAlignment="Center" Minimum="10" Maximum="200" Value="{Binding BlockSize}" 
                    TickPlacement="None" SmallChange="1" LargeChange="10" TickFrequency="1" IsSnapToTickEnabled="True"/>


C# - Mi 14.12.16 18:47

Habs selbst gelöst. Mir ist aber nicht ganz klar warum es so funktioniert.

Das Problem lag daran, dass ich in dem TemplateView Control eine DependencyProperty "Template" hatte, die als DataContext für das Control verwendet wurde, damit ich solche Bindings machen konnte:

XML-Daten
1:
Value="{Binding BlockSize}"                    

Ich habe den DataContext nun leer gelassen und über ElementName gebunden, sprich:

XML-Daten
1:
Value="{Binding  ElementName=Me, Path=OriginalTemplate.BlockSize}"                    

und jetzt funktioniert alles wie es soll. "Me" ist dabei das Control selbst.

Kann mir jemand erklären warum es so geht?