Overblog Suivre ce blog
Editer l'article Administration Créer mon blog

Présentation

  • : Romagny13 - Du .NET,du pur .NET
  • Romagny13 - Du .NET,du pur .NET
  • : Cycle de progression Faire (quelque chose qui marche) -> comprendre ce que l’on fait/comment cela marche -> pousser plus loin les notions
  • Contact

Recherche

Articles Récents

26 avril 2007 4 26 /04 /avril /2007 11:31
[WPF] - Accéder aux controls directement sans passer par le binding
 
Soit :
Ici j’ai une TextBox qui a un Template simpliste pour bien comprendre
(Le template comprend donc une grille avec une TextBox, mais on pourrait facilement ajouter par exemple une image et d’autres controls)
<Window x:Class="WPFFindNameAndVisualTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPFFindNameAndVisualTest" Height="300" Width="300"
    >
 <StackPanel Name="StackPanel1">
    <Button Name="btnTestFindName" Click="btnTestFindName_Click" Height="23"   Width="75">Test FindName()</Button>
    <TextBox Name="txtTestFindName" Width="150" Height="20"/>
 
    <Separator/>
   
    <Button Name="btnTestVisual" Click="btnTestVisual_Click" Height="23"   Width="75">Test Visual</Button>
    <TextBox Name="txtTemplate">
      <TextBox.Template>
        <ControlTemplate >
          <Grid ShowGridLines="Truex:Name="Grid1">
            <TextBox Name="txtTestVisual" Width="150" Height="20" />
          </Grid>
        </ControlTemplate>
      </TextBox.Template>
    </TextBox>
 </StackPanel>
</Window>
 
1 - FrameworkElement.FindName()
Il faut que l’élément soit declaré côté window.g.cs pour réussir à le trouver
public void btnTestFindName_Click(object e, RoutedEventArgs args)
        {
 
            object wantedNode = StackPanel1.FindName("txtTestFindName");
            if (wantedNode is TextBox)
            {
                TextBox wantedChild = wantedNode as TextBox;
                wantedChild.Text = "trouvé";
 
            }
        }
 
Window1.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
//     Ce code a été généré par un outil.
//     Version du runtime :2.0.50727.42
//
//     Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si
//     le code est régénéré.
// </auto-generated>
//------------------------------------------------------------------------------
 
using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
 
namespace WPFFindNameAndVisualTest {
   
   
    ///<summary>
    /// Window1
    ///</summary>
    public partial class Window1 : System.Windows.Window, System.Windows.Markup.IComponentConnector {
       
        internal System.Windows.Controls.StackPanel StackPanel1;
       
        internal System.Windows.Controls.Button btnTestFindName;
       
        internal System.Windows.Controls.TextBox txtTestFindName;
       
        internal System.Windows.Controls.Button btnTestVisual;
       
        internal System.Windows.Controls.TextBox txtTemplate;
       
        private bool _contentLoaded;
       
        ///<summary>
        /// InitializeComponent
        ///</summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
            if (_contentLoaded) {
                return;
            }
            _contentLoaded = true;
            System.Uri resourceLocater = new System.Uri("/WPFFindNameAndVisualTest;component/window1.xaml", System.UriKind.Relative);
            System.Windows.Application.LoadComponent(this, resourceLocater);
        }
       
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
        void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
            switch (connectionId)
            {
            case 1:
            this.StackPanel1 = ((System.Windows.Controls.StackPanel)(target));
            return;
            case 2:
            this.btnTestFindName = ((System.Windows.Controls.Button)(target));
           
            #line 7 "....Window1.xaml"
            this.btnTestFindName.Click += new System.Windows.RoutedEventHandler(this.btnTestFindName_Click);
           
            #line default
            #line hidden
            return;
            case 3:
            this.txtTestFindName = ((System.Windows.Controls.TextBox)(target));
            return;
            case 4:
            this.btnTestVisual = ((System.Windows.Controls.Button)(target));
           
            #line 12 "....Window1.xaml"
            this.btnTestVisual.Click += new System.Windows.RoutedEventHandler(this.btnTestVisual_Click);
           
            #line default
            #line hidden
            return;
            case 5:
            this.txtTemplate = ((System.Windows.Controls.TextBox)(target));
            return;
            }
            this._contentLoaded = true;
        }
    }
}
 
 
2 – FrameworkTemplate.FindName()
 
Permet acceder aux controls d’un template
Donc dans mon cas cela donnerait par exemple pour accéder à la TextBox txtTestVisual :
public void btnTestFindName_Click(object e, RoutedEventArgs args)
        {
            Grid grid = this.txtTemplate.Template.FindName("Grid1", this.txtTemplate) as Grid;
 
            TextBox oTextBox = grid.FindName("txtTestVisual") as TextBox;
            oTextBox.Text = "trouvé grâce à FrameworkTemplate.FindName()";
 
        }
> Thomas Lebrun explique trés bien cela sur son blog
[WPF] Comment accéder aux contrôles existants dans un Template ?
3 – VisualTreeHelper
Permet accéder aux tous controls même ceux d’un template
public void btnTestVisual_Click(object e, RoutedEventArgs args)
        {
            EnumVisual(txtTemplate);
        }
 
        public void EnumVisual(Visual oVisual)
        {
            for (int nVisualChildrenCount = 0; nVisualChildrenCount < VisualTreeHelper.GetChildrenCount(oVisual); nVisualChildrenCount++)
            {
                Visual childVisual;
 
                childVisual = (Visual)VisualTreeHelper.GetChild(oVisual, nVisualChildrenCount);
 
                if (childVisual is TextBox)
                {
                    TextBox wantedChild = childVisual as TextBox;
                    //
                    if (wantedChild.Name == "txtTestVisual")
                    {
                        wantedChild.Text = "trouvé";
                    }
 
                }
 
                //
                EnumVisual(childVisual);
            }
        }
 
 
Liens
FrameworkElement.FindName Method
 
VisualTreeHelper Class 
 
 

Partager cet article

Repost 0
Published by Romagny13 - dans Xaml
commenter cet article

commentaires