none
Vom DataTemplate auf übergeordnetes Framwork-Element zugreifen RRS feed

  • Frage

  • Hallo!

    Wie der Titel sicherlich vermuten lässt, möchte ich von einem DataTemplate auf eine Eigenschaft eines übergeordneten Framwork-Elements, was dieses DataTemplate nutzt, zugreifen. 

    <ListView>
        <ListView.Resources>
            <DataTemplate x:Key="MyDataTemplate">
                <Border Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=GridViewColumn}, Path=ActualWidth}">
    			...
                </Border>
            </DataTemplate>
        </ListView.Resources>
    	...
        <ListView.View>
            <GridView>
                <GridViewColumn CellTemplate="{StaticResource MyDataTemplate}" Width="190" />
    			...
            </GridView>
        </ListView.View>
    </ListView>
    
    

    Dies führt jedoch zu einem Bindingfehler:

    System.Windows.Data Error: 4 : 
    
    Cannot find source for binding with reference 
    'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.GridViewColumn', AncestorLevel='1''. 
    
    BindingExpression:Path=ActualWidth; DataItem=null; target element is 'Border' (Name=''); target property is 'Width' (type 'Double')
    

    Wieso ???

    Ein Binding über Namen funktioniert:

    <ListView>
        <ListView.Resources>
            <DataTemplate x:Key="myDataTemplate">
                <Border Width="{Binding ElementName=myGridColumn, Path=ActualWidth}">
    			...
                </Border>
            </DataTemplate>
        </ListView.Resources>
    	...
        <ListView.View>
            <GridView>
                <GridViewColumn x:Name="myGridColumn" CellTemplate="{StaticResource myDataTemplate}" Width="190" />
    			...
            </GridView>
        </ListView.View>
    </ListView>
    

    Fred.

    Montag, 3. Mai 2021 12:56

Antworten

  • Hallo Fred,

    Dieser Fehler wird wahrscheinlich verursacht, da Deine DataTemplate nicht Teil der visuellen oder logischen Struktur ist und daher keinen verbindlichen Vorgänger (oder einen irgendwelchen Vorgänger) hat, wodurch das ordnungsgemäße Funktionieren der RelativeSource-Eigenschaft verhindert wird. In diesem Fall solltest Du versuchen, die Bindung an die Quelle explizit bereitzustellen, wie im folgenden Thema beschrieben:
    Cannot find source for binding with reference 'RelativeSource FindAncestor'

    Gruß,

    Ivan Dragov

    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    • Als Antwort markiert perlfred Dienstag, 4. Mai 2021 15:17
    Dienstag, 4. Mai 2021 07:32
    Moderator

Alle Antworten

  • Hallo Fred,

    Dieser Fehler wird wahrscheinlich verursacht, da Deine DataTemplate nicht Teil der visuellen oder logischen Struktur ist und daher keinen verbindlichen Vorgänger (oder einen irgendwelchen Vorgänger) hat, wodurch das ordnungsgemäße Funktionieren der RelativeSource-Eigenschaft verhindert wird. In diesem Fall solltest Du versuchen, die Bindung an die Quelle explizit bereitzustellen, wie im folgenden Thema beschrieben:
    Cannot find source for binding with reference 'RelativeSource FindAncestor'

    Gruß,

    Ivan Dragov

    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    • Als Antwort markiert perlfred Dienstag, 4. Mai 2021 15:17
    Dienstag, 4. Mai 2021 07:32
    Moderator
  • Hallo Ivan!

    Dein Ansatz ist richtig, wenn ich auch nicht nachvollziehen kann, wieso das DataTemplate nicht zumindest Teil der logischen Struktur ist.

    Das Prinzip, einen Verweis (über den Proxy) von einem Framework-Objekt zu dem DataTemplate, zu erstellen, finde ich großartig.

    Dem Proxy kann ich für die Data-Bindung eine Relative Source übergeben, da an dieser Stelle der Ancestor gefunden werden kann und im DataTemplate kann ich auf die (Proxy) Resource zugreifen und meinen Pfad auf der Grundlage dieses Ausgangspunktes genau definieren.   Perfekt!

    <ListView.Resources>
        <local:BindingProxy x:Key="proxy" Data="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}}" />
         <DataTemplate x:Key="WeckzeitBezeichnungTemplate">
            <Border Width="{Binding Source={StaticResource proxy}, Path=Data.View.Columns[0].ActualWidth }">
                 ...
            </Border>
        </DataTemplate>
    
    <ListView.View>
         <GridView>
             <GridViewColumn CellTemplate="{StaticResource WeckzeitBezeichnungTemplate}" Width="190" />
                 ...
          </GridView>
    </ListView.View>
    

    In diesem Beispiel übergebe ich dem Proxy die ListView und verweise im DataTemplate auf die erste Spalte der ListView und hole mir die ActualWidth.

    Vielen Dank für deine Lösung!

    Fred.

    Der Vollständigkeit halber ... der Proxy von Cameron MacFarland

     #region Hilfs-Klassen der View
    public class BindingProxy : Freezable
    {
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }
    
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for Data.
        // This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object),
            typeof(BindingProxy), new UIPropertyMetadata(null));
    }
    #endregion




    • Bearbeitet perlfred Dienstag, 4. Mai 2021 15:23
    Dienstag, 4. Mai 2021 15:17