Private Sub Test
...
Dim cp = FindVisualChild(Of ContentPresenter)(ti)
Dim dt = cp.ContentTemplate
Dim z = dt.FindName("imgTabItem", cp)
...
End Sub
Private Function FindVisualChild(Of childItem As DependencyObject)(ByVal obj As DependencyObject) As childItem
For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj) - 1
Dim child As DependencyObject = VisualTreeHelper.GetChild(obj, i)
If child IsNot Nothing AndAlso TypeOf child Is childItem Then
Return CType(child, childItem)
Else
Dim childOfChild As childItem = FindVisualChild(Of childItem)(child)
If childOfChild IsNot Nothing Then
Return childOfChild
End If
End If
Next i
Return Nothing
End Function
<TabControl x:Name="tcProperties"
Grid.Row="3"
Grid.Column="1"
TabStripPlacement="Left">
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<ContentPresenter>
<ContentPresenter.Content>
<StackPanel Orientation="Horizontal"
x:Name="sp">
<Image Height="16"
Name="imgTabItem"
Source="/tpwk;component/Images/Enable16.png">
</Image>
<TextBlock Margin="4"
FontSize="12"
Text="{TemplateBinding Content}"
Width="90" />
</StackPanel>
</ContentPresenter.Content>
</ContentPresenter>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
</TabControl>
|
|
|
Hallo Jens,
sorry Du hast recht. ich bin davon ausgegangen das ich einen so offensichtlichen Fehler gemacht habe den alle außer mir sofort sehen würden. Folgend der Text der Exception: System.InvalidOperationException: Dieser Vorgang ist nur gültig für Elemente, auf die diese Vorlage angewendet wird. Ausgelöst wird er durch die Funktion „FindName“. Ich habe daraufhin einen Blick in die ChildNames Auflistung des DataTemplates geworfen, dort finde ich aber genau meinen gesuchten Namen „imgTabItem“. Danke. – MaHo 18.06.2012
|
||
|
Ich kann es leider gerade nicht ausprobieren. Eine der ersten Fragen die ich mir aber selbst gestellt habe war, ob Du nicht doch über das TabControl und nicht über das TabItem suchen musst. Das DataTemplate gilt zwar für das TabItem aber indirekt hängt es ja am TabControl. Die Meldung klingt ein wenig so, als wäre das TabItem nicht das gültige Element.
Wenn Du einen Tip gibts, was Du mit dem Bild machen möchtest, findet sich vielleicht eine andere Lösung. Du kannst das Bild sicher auch an etwas binden, falls Du es abhängig vom Tabitem wechseln möchtest. – Jens Duczmal 18.06.2012
|
||
|
Der Benutzer soll eine visuelle Rückmeldung erhalten ob auf dem jeweiligen TabItem noch eine Eingabe erforderlich ist…
Image Rot = Eingabe erforderlich Image Grün=Alle Eingaben abgeschlossen Damit er nicht ständig alle einsehen muss… – MaHo 18.06.2012
|
Class DeineKlasse
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Private _inputCompleted As Boolean
Public Property InputCompleted() As Boolean
Get
Return _inputCompleted
End Get
Set(ByVal value As Boolean)
_inputCompleted = value
NotifyPropertyChanged("InputCompleted")
End Set
End Property
End Class
Imports System.Globalization
Public NotInheritable Class BooleanToVisibilityConverter
Implements IValueConverter
Public Property IsReversed() As Boolean
Get
Return m_IsReversed
End Get
Set(ByVal value As Boolean)
m_IsReversed = value
End Set
End Property
Private m_IsReversed As Boolean
Public Property UseHidden() As Boolean
Get
Return m_UseHidden
End Get
Set(ByVal value As Boolean)
m_UseHidden = value
End Set
End Property
Private m_UseHidden As Boolean
Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.Convert
Dim val = System.Convert.ToBoolean(value, CultureInfo.InvariantCulture)
If Me.IsReversed Then
val = Not val
End If
If val Then
Return Visibility.Visible
End If
Return If(Me.UseHidden, Visibility.Hidden, Visibility.Collapsed)
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
<Window.Ressources>
<local:BooleanToVisibilityConverter x:Key="BoolToVisibility"/>
<local:BooleanToVisibilityConverter IsReversed="true" x:Key="NotBoolToVisibility"/>
</Window.Ressources>
<StackPanel Orientation="Horizontal" x:Name="sp">
<Image Height="16"
Source="/tpwk;component/Images/Enable16.png"
Visibility={Binding InputCompleted,
Converter={StaticResource BoolToVisibility}/>
<Image Height="16"
Source="/tpwk;component/Images/Disable16.png"
Visibility={Binding InputCompleted,
Converter={StaticResource NotBoolToVisibility}/>
<TextBlock Margin="4" FontSize="12"
Text="{TemplateBinding Content}"
Width="90" />
</StackPanel>
|
|
|
Hallo Jens,
danke für die ausführliche Antwort. Werde es jetzt so machen ! Aber interessieren würde mich schon noch ob der Ansatz falsch ist auf das Template zugreifen zu wollen… Danke nochmal. – MaHo 19.06.2012
|
||
|
Nun ich weiss nicht, ob man hier direkt von falsch oder richtig reden kann. Von der Idee her ist es nicht notwendig, da WPF für solche Dinge eben andere Möglichkeiten bietet. Allerdings ist das halt mitunter mit vielen Änderungen versehen. Dein Ansatz wäre WPF-Fenster mit "CodeBehind" also Quellcode direkt am WPF. Meiner mit MVVM (such hier mal danach, Du wirst viel darüber finden). Dann nur wegen eines Icons "umzusteigen" rechtfertigt den Aufwand evtl. nicht. MVVM ist halt nur die empfohlende Vorgehensweise. Deshalb muss sie nicht die einzig richtige Lösung sein. Ich warte Infos anderer hier.
– Jens Duczmal 19.06.2012
|
||
|
Das eigentliche Programm ist nach dem MVVM Konzept aufgebaut…keine Frage für größere Projekte ...nur bei dem "kleinen" Tool handelt es sich um ein Datenmigrationsprogramm das ich eigentlich ohne die Trennung UI / Logik aufbauen wollte.
– MaHo 20.06.2012
|
||
|
Ah, sorry. Tja, da ich mit Templates/Styles so halbwegs auf Kriegsfuss stehe bzw. mich immer noch in WPF einarbeite, war das meine einzige Lösung :) Mehr mangels Wissen.
– Jens Duczmal 20.06.2012
|
Die da wäre? Und in welcher der beiden Methoden? Fehlermeldungen enthalten häufig interessante Texte die auf die Fehlerursache hinweisen :)