none
Sackgasse? RRS feed

  • Frage

  • Hallo!

    Offenbar gerate ich hier in eine Sackgasse ...

    Ich habe folgendes gemacht:

    1. UserControl UC1 (Etage) mit DP's erstellt.

    2. UserControl UC2 (LageView) erstellt.

    In UC2 instanziere ich UC1's in einer Schleife. In UC2 reiche ich die DP's von UC1 durch, damit diese von UC2 aus, ansprechbar werden und definiere noch zusätzliche DP's (wie z.B. die Anzahl der zu erstellenden UC1-Instanzen).

    Wenn ich in einer Applikation UC1-Instanzen (Etage) erstelle, kann ich alle DP's (mit allen anhängigen Eigenschaften) übergeben und sie werden mir immer korrekt angezeigt:

    <GES:Etage  nPosition="2" VerticalAlignment="Top" MinHeight="20" Margin="0,50,0,0" 
            BezeichnungWidth="50" Bezeichnung="Etage" BezeichnungAbstand="5,0,0,0" 
            BezeichnungFontSize="15" BezeichnungFontWeight="Bold" BezeichnungFontFamily="Arial" BezeichnungForeGround="Blue"                     
            WohnungAbstandLinks="10,2,5,2" WohnungAbstandMitte="5,2" WohnungAbstandRechts="5,2,10,2" 
            WohnungRahmen="2" WohnungRFarbeDeaktiv="Black" WohnungRFarbeAktiv="Red"
            Etage_Rahmen="0,2" Etage_RahmenFarbe="Aquamarine" Etage_MinHeight="40" >
        <GES:Etage.WohnungHGFarbeAktiv>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="LightGray" Offset="0"/>
                <GradientStop Color="WhiteSmoke" Offset="0.5"/>
                <GradientStop Color="LightGray" Offset="1"/>
            </LinearGradientBrush>
        </GES:Etage.WohnungHGFarbeAktiv>
        <GES:Etage.WohnungHGFarbeDeaktiv>
            <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                <GradientStop Color="Gray" Offset="0"/>
                <GradientStop Color="LightGray" Offset="0.5"/>
                <GradientStop Color="Gray" Offset="1"/>
            </LinearGradientBrush>
        </GES:Etage.WohnungHGFarbeDeaktiv>
    </GES:Etage>

    UC1 - Etage

    (Die Bezeichnung wird Groß und Fett dargestellt, die Farbverläufe bei aktiven und deaktiven Wohnungen sind vorhanden)

    Wenn ich UC2 instanziere (mit den gleichen, durchgereichten DP's):

    <GES:LageView x:Name="lv1"  VerticalAlignment="Bottom"  
                BezeichnungWidth="20" BezeichnungFontFamily="Times New Roman" BezeichnungFontSize="15" BezeichnungAbstand="2,0" BezeichnungFontWeight="Bold"
                WohnungAbstandLinks="4,2" WohnungAbstandMitte="4,2" WohnungAbstandRechts="4,2,6,2"  
                WohnungRFarbeDeaktiv="Black" WohnungRFarbeAktiv="Red" WohnungRahmen="2"
                Etage_MinHeight="30"
                zGES_Lage="0202" nEtagen="5" >
        <GES:LageView.WohnungHGFarbeDeaktiv>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="Gray" Offset="0"/>
                <GradientStop Color="LightGray" Offset="0.5"/>
                <GradientStop Color="Gray" Offset="1"/>
            </LinearGradientBrush>
        </GES:LageView.WohnungHGFarbeDeaktiv>
        <GES:LageView.WohnungHGFarbeAktiv>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="LightGray" Offset="0"/>
                <GradientStop Color="WhiteSmoke" Offset="0.5"/>
                <GradientStop Color="LightGray" Offset="1"/>
            </LinearGradientBrush>
        </GES:LageView.WohnungHGFarbeAktiv>
    </GES:LageView>

    Zur Kontrolle die Anzeige in der Applikation:

    <TextBlock Text="{Binding ElementName=lv1, Path=BezeichnungFontWeight, UpdateSourceTrigger=PropertyChanged, Mode=OneWay , StringFormat={} BezeichnungFontWeight: {0}}" Margin="0,15" VerticalAlignment="Top" />
    <TextBlock Text="{Binding ElementName=lv1, Path=WohnungHGFarbeDeaktiv, UpdateSourceTrigger=PropertyChanged, Mode=OneWay , StringFormat={} WohnungHGFarbeDeaktiv: {0}}" Margin="0,30" VerticalAlignment="Top" />

    werden die anhängigen Eigenschaften nicht mehr angezeigt:

    Nebenbei: Im VisualStudio komischer Weise schon:

    Deshalb meine Fragen:

    1. Sollte man UserControl's nicht verschachteln? (Ich benötige aber eine variable Anzahl von UC1 in UC2)

    2. Kann man die anhängigen Eigenschaften auch noch "übernehmen"?

    3. Löst ein ViewModel das Problem? 


    • Bearbeitet perlfred Freitag, 19. August 2016 09:52
    Freitag, 19. August 2016 09:30

Antworten

  • Hi Fred,
    in Deiner Methode "setAnzahlUC1" setzt Du voraus, dass "BrushUC1" bereits von außen zugewiesen (gebunden) wurde. Wenn die Zuweisung aber erst später ausgeführt wird, dann steht nur der alte Wert aus den PropertyMetaData zur Verfügung. Da es keine Vorschrift zur Reihenfolge der Ausführung der Zuweisung der Werte aus den Bindungen gibt, musst Du die unterschiedlich mögliche Reihenfolge berücksichtigen, z.B. so:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace WpfControlLibrary1
    {
      public partial class UserControl43_2 : UserControl
      {
        public UserControl43_2() { InitializeComponent(); }
    
        public Brush BrushUC1
        {
          get { return (Brush)GetValue(BrushUC1Property); }
          set { SetValue(BrushUC1Property, value); }
        }
        // Using a DependencyProperty as the backing store for BrushUC2.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BrushUC1Property =
            DependencyProperty.Register("BrushUC1",
              typeof(Brush),
              typeof(UserControl43_2),
              new PropertyMetadata(Brushes.Magenta,new PropertyChangedCallback(aktuUC1)));
    
        // DP: nAnzahlUC1 - Anzahl der UC1 Instanzen
        private static readonly DependencyProperty nAnzahlUC1Property =
          DependencyProperty.Register("nAnzahlUC1",
            typeof(int), typeof(UserControl43_2),
            new PropertyMetadata(-1, new PropertyChangedCallback(aktuUC1)));
        public int nAnzahlUC1
        {
          get { return (int)GetValue(nAnzahlUC1Property); }
          set { SetValue(nAnzahlUC1Property, value); }
        }
        private static void aktuUC1(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          setChilds((UserControl43_2)d);
        }
        private static void setChilds(UserControl43_2 uc2)
        {
          if (uc2.nAnzahlUC1 < 0) return;
          uc2.sp.Children.Clear();                    // Alle bestehenden Einträge löschen
          for (int i = uc2.nAnzahlUC1; i > 0; i--)              // So viele UC1 Instanzen erzeugen, wie angegeben
          {
            UserControl43_1 uc1 = new UserControl43_1();  // Neue UC1-Instanz erstellen
            uc1.BrushUC1 = uc2.BrushUC1;            // DP-Wert: BrushUC1 "übernehmen"
            uc1.Margin = new Thickness(0, 0, 0, 3); // Abstand zwischen den UC1-Instanzen definieren
            uc2.sp.Children.Add(uc1);               // Neue Etage dem StackPanel hinzufügen                
          }
        }
      }
    }



    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen! Leben retten!
    Wir essen Opa.
    Wir essen, Opa.


    • Bearbeitet Peter Fleischer Sonntag, 21. August 2016 14:47
    • Als Antwort markiert perlfred Montag, 22. August 2016 13:24
    Sonntag, 21. August 2016 14:45

Alle Antworten

  • Hi,
    zu 1.: natürlich kann man verschachteln.

    zu 2.: Unklar ist, was Du mit "übernehmen" meinst. Wenn es das Kopieren der Eigenschaften in den Code einer anderen Klasse gemeint ist, dann ist lediglich zu beachten, dass die abhängige Eigenschaft dann auf den richtigen Typ verweist.

    zu 3.: Das Problem ist unklar, da unklar ist, was Du mit "übergeben" meinst, s. zu 2. Ein ViewModel wird im Entwurfsmuster MVVM eingesetzt. Da solch ein Entwurfsmuster für Bindungen genutzt wird, kann es passieren, dass durch anderes Zeitverhalten auch die Ansicht anders aussehen kann. 


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen! Leben retten!
    Wir essen Opa.
    Wir essen, Opa.

    Freitag, 19. August 2016 14:53
  • Hallo Peter!

    Danke für deine Antwort! 

    Manchmal steckt man zu tief in einem Problem um sich verständlich auszudrücken, deshalb hatte ich das Problem nochmal sehr übersichtlich als kleines Projekt erstellt:

    Ich habe ein UserControl UserControl1, das lediglich aus einem Border besteht und nur das DP: BrushUC1 besitzt:

    <UserControl x:Name="uc1" x:Class="uc2.UserControl1"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:uc2"
                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
                 mc:Ignorable="d" 
                 d:DesignHeight="40" d:DesignWidth="100">
        <Border Background="{Binding ElementName=uc1, Path=BrushUC1}" BorderThickness="2" BorderBrush="Gray" Height="20" Width="80" />
    </UserControl>
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace uc2
    {
        /// <summary>
        /// Interaktionslogik für UserControl1.xaml
        /// </summary>
        public partial class UserControl1 : UserControl
        {
            public UserControl1()
            {
                InitializeComponent();
            }
    
            // DP BrushUC1
            private static readonly DependencyProperty BrushUC1Property = DependencyProperty.Register("BrushUC1", typeof(Brush), typeof(UserControl1), new PropertyMetadata(Brushes.Blue));
            public Brush BrushUC1
            {
                get { return (Brush)GetValue(BrushUC1Property); }
                set { SetValue(BrushUC1Property, value); }
            }
        }
    }

    Das UserControl2 besteht lediglich aus einem StackPanel, in dem ich, abhängig von der UC2-DP: nAnzahlUC-1 mal UC1 Instanzen erzeuge:

    <UserControl x:Name="uc2" x:Class="uc2.UserControl2"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:uc2"
                 mc:Ignorable="d" 
                 d:DesignHeight="100" d:DesignWidth="300">
        <StackPanel x:Name="sp"/>
    </UserControl>


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace uc2
    {
        /// <summary>
        /// Interaktionslogik für UserControl2.xaml
        /// </summary>
        public partial class UserControl2 : UserControl
        {
            public UserControl2()
            {
                InitializeComponent();
            }
    
            #region (Äquivalente) DP's UC1
            // DP BrushUC1
            private static readonly DependencyProperty BrushUC1Property = DependencyProperty.Register("BrushUC1", typeof(Brush), typeof(UserControl2), new PropertyMetadata(Brushes.Red));
            public Brush BrushUC1
            {
                get { return (Brush)GetValue(BrushUC1Property); }
                set { SetValue(BrushUC1Property, value); }
            }
            #endregion
            
            #region DP's UC2
            // DP: nAnzahlUC1 - Anzahl der UC1 Instanzen
            private static readonly DependencyProperty nAnzahlUC1Property = DependencyProperty.Register("nAnzahlUC1", typeof(int), typeof(UserControl2), new PropertyMetadata(0, new PropertyChangedCallback(aktuAnzahlUC1)));
            public int nAnzahlUC1
            {
                get { return (int)GetValue(nAnzahlUC1Property); }
                set { SetValue(nAnzahlUC1Property, value); }
            }
            #endregion
    
            private static void aktuAnzahlUC1(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                if ((int)e.NewValue > -1) { setAnzahlUC1((int)e.NewValue, (UserControl2)d); }        
            }
    
            private static void setAnzahlUC1(int nUC1, UserControl2 uc2)
            {
                uc2.sp.Children.Clear();                    // Alle bestehenden Einträge löschen
                for (int i = nUC1; i > 0; i--)              // So viele UC1 Instanzen erzeugen, wie angegeben
                {
                    UserControl1 uc1 = new UserControl1();  // Neue UC1-Instanz erstellen
                    uc1.BrushUC1 = uc2.BrushUC1;            // DP-Wert: BrushUC1 "übernehmen"
                    uc1.Margin = new Thickness(0, 0, 0, 3); // Abstand zwischen den UC1-Instanzen definieren
                    uc2.sp.Children.Add(uc1);               // Neue Etage dem StackPanel hinzufügen                
                }
            }
        }
    }

    Mit übernehmen meine ich, dass ich die Werte der DP's von UC2 in die Werte der DP's der UC1-Instanzen kopiere (setAnzahlUC1).

    Beim instanzieren dieser UserControl's (= Applikation) trat nun das Problem auf, dass die Werte aller anhängigen Eigenschaften, also Eigenschaften die in XAML nach der direkten Instanz angehängt sind, nicht an das UserControl1 übergeben werden.

    Meine kleine Beispiel-Applikation veranschaulicht dies:

    <Window x:Class="ucApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:uc="clr-namespace:uc2;assembly=uc2"
            Title="MainWindow" Height="350" Width="600">
        <Window.Resources>
            <LinearGradientBrush x:Key="brVerlauf" EndPoint="0,0" StartPoint="1,0">
                <GradientStop Color="Yellow" Offset="0"/>
                <GradientStop Color="Blue" Offset="1"/>
            </LinearGradientBrush>
        </Window.Resources>    
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Text="UC1-Instanz: " VerticalAlignment="Center" />
            <uc:UserControl1 Grid.Column="1" Margin="0,3,0,0"/>
            <TextBlock Grid.Column="2" Text="Korrekt, DP-Metadaten werden verwendet" VerticalAlignment="Center" />
            <TextBlock Grid.Row="1" Text="UC1-Instanz mit DP-Wert: " VerticalAlignment="Center" />
            <uc:UserControl1 Grid.Row="1" Grid.Column="1" BrushUC1="Yellow" Padding="0,3"/>
            <TextBlock Grid.Row="1" Grid.Column="2" Text="Korrekt, DP-Daten werden verwendet" VerticalAlignment="Center" />
            <TextBlock Grid.Row="2" Text="UC1-Instanz mit anhängigen DP-Wert: " VerticalAlignment="Center" />
            <uc:UserControl1 Grid.Row="2" Grid.Column="1" Margin="0,3" >
                <uc:UserControl1.BrushUC1>
                    <LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
                        <GradientStop Color="Yellow" Offset="0"/>
                        <GradientStop Color="Blue" Offset="1"/>
                    </LinearGradientBrush>
                </uc:UserControl1.BrushUC1>
            </uc:UserControl1>
            <TextBlock Grid.Row="2" Grid.Column="2" Text="Korrekt, Anhängige DP-Daten werden verwendet" VerticalAlignment="Center" />
            <TextBlock Grid.Row="3" Text="UC2-Instanz" VerticalAlignment="Center" />
            <uc:UserControl2 Grid.Row="3" Grid.Column="1" nAnzahlUC1="2" Margin="0,3"/>
            <TextBlock Grid.Row="3" Grid.Column="2" Text="Korrekt, DP-Metadaten werden verwendet" VerticalAlignment="Center" />
            <TextBlock Grid.Row="4" Text="UC2-Instanz mit DP-Wert: " VerticalAlignment="Center" />
            <uc:UserControl2 Grid.Row="4" Grid.Column="1" BrushUC1="Yellow" nAnzahlUC1="2" Margin="0,3"/>
            <TextBlock Grid.Row="4" Grid.Column="2" Text="Korrekt, DP-Daten werden verwendet" VerticalAlignment="Center" />
            <TextBlock Grid.Row="5" Text="UC2-Instanz mit anhängigen DP-Wert: " VerticalAlignment="Center" />
            <uc:UserControl2 Grid.Row="5" Grid.Column="1" nAnzahlUC1="2" Margin="0,3">
                <uc:UserControl2.BrushUC1>
                    <LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
                        <GradientStop Color="Yellow" Offset="0"/>
                        <GradientStop Color="Blue" Offset="1"/>
                    </LinearGradientBrush>
                </uc:UserControl2.BrushUC1>
            </uc:UserControl2>
            <TextBlock Grid.Row="5" Grid.Column="2" VerticalAlignment="Center">
                <Bold>Fehler!</Bold>
                <LineBreak/> Zur <Bold>Laufzeit</Bold> werden die <Bold>Metadaten</Bold> verwendet! 
                <LineBreak/> Im VS korrekte Anzeige!
            </TextBlock>
            <TextBlock Grid.Row="6" VerticalAlignment="Center">
                UC2-Instanz mit DP-Wert als <Bold>Resource</Bold>:
            </TextBlock>
            <uc:UserControl2 Grid.Row="6" Grid.Column="1" BrushUC1="{StaticResource brVerlauf}" nAnzahlUC1="2" Margin="0,3"/>
            <TextBlock Grid.Row="6" Grid.Column="2" VerticalAlignment="Center">
                <Bold>Korrekt!</Bold>
                <LineBreak/> Zur <Bold>Laufzeit</Bold> werden die Resource-Daten verwendet! 
                <LineBreak/> Im <Bold>VS</Bold> werden die Metadaten angezeigt!
            </TextBlock>        
        </Grid>
    </Window>

    Die Ergebnisse :

    VS:

    Farbverlauf = anhängige Daten.

    Als erste "Lösung" habe ich die Verwendung von Resourcen gefunden. Diese Lösung schränkt die Flexibilität des (Mutter) UserControl's aber sehr ein (bei Kind-UserControl's funktioniert es ja immer tadellos!). Deshalb habe ich an der Methode, UserControl's zu verschachteln, gezweifelt.

    Welche Lösung schlägst du in so einem (sicher sehr oft notwendigen Fall) vor?

    Fred.
    • Bearbeitet perlfred Samstag, 20. August 2016 06:31
    Samstag, 20. August 2016 06:21
  • Hi Fred,
    ohne genau ins Detail zu gehen, ist erst einmal unklar, wozu Du in Deinem UC1 die DP BrushUC1Property hast. Dies wird im UC1 nicht genutzt, da weder in einem DataContext noch im Border selbst eine Source angegeben ist. Da Du im UC2 eine gleichnamige DP hast, wird u.U. diese genutzt. Voraussetzung dafür ist aber auch, dass die Source entsprechend gesetzt ist. Nach erstem Überfliegen, konnte ich das aber nicht erkennen. Zeil mal, wo Du die Source-Eigenschaften der Binding-Objekte setzt bzw. über welchen DataContext sie bereitstehen.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen! Leben retten!
    Wir essen Opa.
    Wir essen, Opa.

    Samstag, 20. August 2016 08:49
  • Hallo Peter!

    Die DP: BrushUC1 wird in der Background-Eigenschaft des Border-Objekt's in UC1 über  den Elementnamen, der auf das UserControl1 selbst verweist, gebunden:

    <Border Background="{Binding ElementName=uc1, Path=BrushUC1}" BorderThickness="2" />


    Deshalb funktionieren auch alle Beispiele, in denen ich nur UC1 instanziere.  Die Namen der DP's in UC2 habe ich gleich den Namen der UC1 Property gesetzt, damit ich den direkten inhaltlichen Bezug bei Instanzen von UC2 habe.

    Hier vielleicht noch einmal der DP-Werte übernehmen Sachverhalt (setAnzahlUC1 in UC2) 

    An dieser Stelle übergebe ich die Werte der (gleichnamigen) DP2 Propertys an die Instanzen der DP1 Property und genau hier musste ich feststellen, daß die DP2 Property nicht die Werte von anhängigen Eigenschaften beinhaltet. Was auch wieder logisch ist, da zu dem Zeitpunkt des festlegens der Eigenschaft in XAML, die anhängige Eigenschaft noch garnicht definiert wurde. (Gilt auch für FontWeight, FontSize usw. der GradientBrush war nur das anschaulichste Beispiel)

    Da das Verschachteln von UC's aber doch keine Ausnahme sein kann und man anhängige Eigenschaften auch oft benutzt, muss es doch dafür bereits eine Lösung geben!

    Wünsche noch einen schönen Sonntag, 

    Fred.

    Anmerkung:

    Was mich besonders irritiert, wenn ich nur UC1 instanziere beinhalten die DP's die anhängigen Eigenschaften (siehe Bild). Warum beinhalten die gleichen DP's die anhängigen Eigenschaften bei UC2, wenigstens in UC2, nicht???




    • Bearbeitet perlfred Sonntag, 21. August 2016 08:50
    Sonntag, 21. August 2016 08:00
  • Hi Fred,
    in Deiner Methode "setAnzahlUC1" setzt Du voraus, dass "BrushUC1" bereits von außen zugewiesen (gebunden) wurde. Wenn die Zuweisung aber erst später ausgeführt wird, dann steht nur der alte Wert aus den PropertyMetaData zur Verfügung. Da es keine Vorschrift zur Reihenfolge der Ausführung der Zuweisung der Werte aus den Bindungen gibt, musst Du die unterschiedlich mögliche Reihenfolge berücksichtigen, z.B. so:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace WpfControlLibrary1
    {
      public partial class UserControl43_2 : UserControl
      {
        public UserControl43_2() { InitializeComponent(); }
    
        public Brush BrushUC1
        {
          get { return (Brush)GetValue(BrushUC1Property); }
          set { SetValue(BrushUC1Property, value); }
        }
        // Using a DependencyProperty as the backing store for BrushUC2.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BrushUC1Property =
            DependencyProperty.Register("BrushUC1",
              typeof(Brush),
              typeof(UserControl43_2),
              new PropertyMetadata(Brushes.Magenta,new PropertyChangedCallback(aktuUC1)));
    
        // DP: nAnzahlUC1 - Anzahl der UC1 Instanzen
        private static readonly DependencyProperty nAnzahlUC1Property =
          DependencyProperty.Register("nAnzahlUC1",
            typeof(int), typeof(UserControl43_2),
            new PropertyMetadata(-1, new PropertyChangedCallback(aktuUC1)));
        public int nAnzahlUC1
        {
          get { return (int)GetValue(nAnzahlUC1Property); }
          set { SetValue(nAnzahlUC1Property, value); }
        }
        private static void aktuUC1(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          setChilds((UserControl43_2)d);
        }
        private static void setChilds(UserControl43_2 uc2)
        {
          if (uc2.nAnzahlUC1 < 0) return;
          uc2.sp.Children.Clear();                    // Alle bestehenden Einträge löschen
          for (int i = uc2.nAnzahlUC1; i > 0; i--)              // So viele UC1 Instanzen erzeugen, wie angegeben
          {
            UserControl43_1 uc1 = new UserControl43_1();  // Neue UC1-Instanz erstellen
            uc1.BrushUC1 = uc2.BrushUC1;            // DP-Wert: BrushUC1 "übernehmen"
            uc1.Margin = new Thickness(0, 0, 0, 3); // Abstand zwischen den UC1-Instanzen definieren
            uc2.sp.Children.Add(uc1);               // Neue Etage dem StackPanel hinzufügen                
          }
        }
      }
    }



    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen! Leben retten!
    Wir essen Opa.
    Wir essen, Opa.


    • Bearbeitet Peter Fleischer Sonntag, 21. August 2016 14:47
    • Als Antwort markiert perlfred Montag, 22. August 2016 13:24
    Sonntag, 21. August 2016 14:45
  • Hallo Peter!

    Ist ja ganz schön verzwickt. Das es wieder an der Reihenfolge der Zuweisung der Werte der DP's liegen könnte, hatte ich mir schon gedacht. Aber wie man die Reihenfolge von Anhängigen Eigenschaften verändern könnte (oder umgehen, so wie du es gemacht hast), so weit hat es bei mir nicht gereicht.

    Clever ist auch das Detail, dass genau auf den Wert der Anzahl DP abgefragt wird, nicht auf e.NewValue, da dieser ja jetzt vom jeweiligen Property-Typ abhängt.

    Vielen Dank für diese Lösung!!!!  Jetzt klappt's auch mit der Wertübergabe bei verschachtelten UC's! :-)

    Montag, 22. August 2016 13:38