none
Custom Control Erweiterte Befehle RRS feed

  • Frage

  • Hallo zusammen.

    Ich hätte ne kurze und knappe Frage: Wie schaffe ich es ein Control zu schreiben, welches ich dann in XAML (WPF) wie ein Grid, TextBlock usw. in einem anderen Control aufrufen kann? Z.B. Grid.Row="4" in einer TextBox. Wie kann ich eine Property schreiben wie das "Grid.Row" was in jedem anderen Control genutzt werden kann?

    Dankeschön im Voraus!

    MfG Flo


    FLOGERSOFT.de - Top Apps, wie z.B. 'Die Taschenlampe' oder ganz neu dabei: 'LiveClock' die Echtzeituhr für ihre Windows Phone Live-Kachel - mit Wettervorhersage!

    Freitag, 17. August 2018 22:23

Antworten

  • Hi Flo,
    solche Eigenschaften werden als DependencyProperty mit RegisterAttached bereitgestellt. Hier mal eine Demo in C#.NET

    XAML des Window

    <Window x:Class="WpfApp1.Window67"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window67" Height="450" Width="800">
      <Grid>
        <local:Window67UC1>
          <local:Window67UC2 local:Window67UC1.Row="1" />
        </local:Window67UC1>
      </Grid>
    </Window>
    

    Dazu CodeBehind des 1. UserControls mit der DependencyProperty (im Grid des XAML steht nichts weiter drin):

    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApp1
    {
      /// <summary>
      /// Interaction logic for Window67UC1.xaml
      /// </summary>
      public partial class Window67UC1 : UserControl
      {
        public Window67UC1() => InitializeComponent();
    
        public static DependencyProperty RowProperty =
      DependencyProperty.RegisterAttached("Row",
                                          typeof(int),
                                          typeof(Window67UC1),
                                          new FrameworkPropertyMetadata(0,
                                            FrameworkPropertyMetadataOptions.AffectsRender,
                                            new PropertyChangedCallback(OnRowChanged)));
    
        private static void OnRowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          var uc2 = d as Window67UC2;
          if (uc2 != null) uc2.Zahl = (int)e.NewValue;
        }
    
        public int Row
        {
          get { return (int)GetValue(RowProperty); }
          set { SetValue(RowProperty, value); }
        }
    
        public static void SetRow(UIElement element, int value) => element.SetValue(RowProperty, value);
    
        public static int GetRow(UIElement element) => (int)(element.GetValue(RowProperty));
    
      }
    }
    

    XAML des zweiten UserControls:

    <UserControl x:Class="WpfApp1.Window67UC2"
                 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:WpfApp1"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
      <Grid>
        <Label Content="{Binding Zahl}"/>
      </Grid>
    </UserControl>

    Und dazu der CodeBehind des zweiten UserControls:

    using System.Windows.Controls;
    
    namespace WpfApp1
    {
      /// <summary>
      /// Interaction logic for Window67UC2.xaml
      /// </summary>
      public partial class Window67UC2 : UserControl
      {
        public Window67UC2()
        {
          InitializeComponent();
    
          this.DataContext = this;
        }
    
        public int Zahl { get; set; }
      }
    }

    In der Demo wird die im Hauptprogramm im eingebetteten 2. UserControl der Eigenschaft "Row" des ersten UserControls zugewiesene Wert dann im 2. UserControl angezeigt.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort vorgeschlagen Peter Fleischer Montag, 20. August 2018 17:03
    • Als Antwort markiert Flo0806 Dienstag, 28. August 2018 17:02
    Montag, 20. August 2018 17:03
  • Hallo Flo,

    Schau mal, ob folgende zwei Beispiele Dir weiterhelfen werden:
    WPF: Making Properties of embedded control from template in custom control available
    Changing Themes and Nested Custom controls

    Im ersten Thread wird das zweite benutzerdefinierte Steuerelement in ein Grid eingebettet.

    Gruß,
    Dimitar


    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 Flo0806 Dienstag, 28. August 2018 17:02
    Montag, 20. August 2018 14:01
    Moderator

Alle Antworten

  • Hallo Flo,

    Schau mal, ob folgende zwei Beispiele Dir weiterhelfen werden:
    WPF: Making Properties of embedded control from template in custom control available
    Changing Themes and Nested Custom controls

    Im ersten Thread wird das zweite benutzerdefinierte Steuerelement in ein Grid eingebettet.

    Gruß,
    Dimitar


    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 Flo0806 Dienstag, 28. August 2018 17:02
    Montag, 20. August 2018 14:01
    Moderator
  • Hi Flo,
    solche Eigenschaften werden als DependencyProperty mit RegisterAttached bereitgestellt. Hier mal eine Demo in C#.NET

    XAML des Window

    <Window x:Class="WpfApp1.Window67"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window67" Height="450" Width="800">
      <Grid>
        <local:Window67UC1>
          <local:Window67UC2 local:Window67UC1.Row="1" />
        </local:Window67UC1>
      </Grid>
    </Window>
    

    Dazu CodeBehind des 1. UserControls mit der DependencyProperty (im Grid des XAML steht nichts weiter drin):

    using System.Windows;
    using System.Windows.Controls;
    
    namespace WpfApp1
    {
      /// <summary>
      /// Interaction logic for Window67UC1.xaml
      /// </summary>
      public partial class Window67UC1 : UserControl
      {
        public Window67UC1() => InitializeComponent();
    
        public static DependencyProperty RowProperty =
      DependencyProperty.RegisterAttached("Row",
                                          typeof(int),
                                          typeof(Window67UC1),
                                          new FrameworkPropertyMetadata(0,
                                            FrameworkPropertyMetadataOptions.AffectsRender,
                                            new PropertyChangedCallback(OnRowChanged)));
    
        private static void OnRowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          var uc2 = d as Window67UC2;
          if (uc2 != null) uc2.Zahl = (int)e.NewValue;
        }
    
        public int Row
        {
          get { return (int)GetValue(RowProperty); }
          set { SetValue(RowProperty, value); }
        }
    
        public static void SetRow(UIElement element, int value) => element.SetValue(RowProperty, value);
    
        public static int GetRow(UIElement element) => (int)(element.GetValue(RowProperty));
    
      }
    }
    

    XAML des zweiten UserControls:

    <UserControl x:Class="WpfApp1.Window67UC2"
                 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:WpfApp1"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
      <Grid>
        <Label Content="{Binding Zahl}"/>
      </Grid>
    </UserControl>

    Und dazu der CodeBehind des zweiten UserControls:

    using System.Windows.Controls;
    
    namespace WpfApp1
    {
      /// <summary>
      /// Interaction logic for Window67UC2.xaml
      /// </summary>
      public partial class Window67UC2 : UserControl
      {
        public Window67UC2()
        {
          InitializeComponent();
    
          this.DataContext = this;
        }
    
        public int Zahl { get; set; }
      }
    }

    In der Demo wird die im Hauptprogramm im eingebetteten 2. UserControl der Eigenschaft "Row" des ersten UserControls zugewiesene Wert dann im 2. UserControl angezeigt.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort vorgeschlagen Peter Fleischer Montag, 20. August 2018 17:03
    • Als Antwort markiert Flo0806 Dienstag, 28. August 2018 17:02
    Montag, 20. August 2018 17:03