2017-02-14 1 views
0

J'ai une application avec 4 onglets. Dans les trois premiers onglets, j'ai quelques GridColumns remplis d'éléments (Boutons, CheckBoxes, ComboBoxes, Labels etc). Chaque onglet a des éléments différents.Clone un GridColumn en conservant les gestionnaires d'événements (ClickEvents) et les propriétés de ses éléments identiques

Ce que je veux faire, est de copier/clone uniquement les colonnes choisies dans chaque onglet à l'onglet 4, pour que je puisse avoir une meilleure modification de mes données. Chaque colonne clonée doit avoir la même fonctionnalité que sa "mère".

J'ai réussi à avoir les colonnes que je sélectionne dans mon onglet « fin », mais les éléments de celui-ci ne possèdent pas les mêmes fonctions et eventhandlers que celles d'origine. Comment puis-je faire en sorte que les colonnes clonées soient les mêmes que celles d'origine? Est-ce une bonne façon de cloner les colonnes que j'ai utilisées?

J'ai fait un simple échantillon de ma demande, pour vous montrer son format. J'écris du code en C# et WPF.

Modifié XAML:

<Window x:Class="WpfApp1.MainWindow" 
    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="MainWindow" Height="500" Width="700"> 
<Grid> 
    <TabControl x:Name="tabControl"> 
     <TabItem Header="Tab1"> 
      <Grid x:Name="tab1"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition /> 
        <ColumnDefinition /> 
        <ColumnDefinition /> 
       </Grid.ColumnDefinitions> 
       <StackPanel x:Name="tab1stack1" Grid.Column="0"> 
        <Label x:Name="lbl1" Content="Col1" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,10" /> 
        <TextBox x:Name="txt1" Width="50" Margin="0,0,0,10" /> 
        <Button x:Name="btn1" Content="Btn1" Width="50" Margin="0,0,0,10" /> 
        <CheckBox x:Name="ckb1" Content="Col1" HorizontalAlignment="Center" Margin="0,0,0,10" /> 
       </StackPanel> 
       <StackPanel x:Name="tab1stack2" Grid.Column="1"> 
        <Label Content="Col2" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,10" /> 
        <TextBox x:Name="txt2" Width="50" Margin="0,0,0,10" /> 
        <Button Content="Btn2" Width="50" Margin="0,0,0,10" /> 
        <CheckBox Content="Col2" HorizontalAlignment="Center" Margin="0,0,0,10" /> 
       </StackPanel> 
       <Grid x:Name="ao1" Grid.Column="2"> 
        <Label x:Name="aol1" Content="{Binding Path=Text, ElementName=aot1}" HorizontalAlignment="Center" Margin="0,2,0,0" VerticalAlignment="Top" MouseDoubleClick="aol1_MouseDoubleClick" ToolTip="Double-Click to rename, and press Enter to apply."/> 
        <TextBox x:Name="aot1" HorizontalAlignment="Center" Height="26" Margin="0,2,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Text="AnalogOut1 [Ch0]" KeyDown="aot1_KeyDown" Visibility="Hidden" LostFocus="aot1_LostFocus" /> 
        <StackPanel Margin="0,30,0,0"> 
         <StackPanel Orientation="Vertical" Margin="0,10,0,0" HorizontalAlignment="Left" > 
          <CheckBox x:Name="ao1enable" Content="Enable" Margin="0,0,0,10" HorizontalAlignment="Left" Padding="4,0,0,0" Unchecked="ao1enable_Unchecked" /> 
          <CheckBox x:Name="ao1live" Content="Live" HorizontalAlignment="Left" Padding="4,0,0,0" /> 
         </StackPanel> 
         <Button x:Name="ao1kickout" Content="Kickout" Margin="10" HorizontalAlignment="Center" Click="ao1kickout_Click" BorderBrush="Red" /> 
         <Label x:Name="lb_amp1" Content="Amplitude:" HorizontalAlignment="Center" Margin="0,10,0,0" /> 
         <StackPanel Orientation="Horizontal" Margin="0" HorizontalAlignment="Center"> 
          <TextBox x:Name="txt_an_amp1" Width="50" Height="20" BorderThickness="1,1,0,1" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" /> 
          <Label Content="V" Width="25" BorderThickness="0,1,1,1" Margin="0" HorizontalAlignment="Right" Height="20" Padding="0" BorderBrush="#FFABADB3" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" /> 
         </StackPanel> 
         <TextBlock x:Name="tb_no_an_amp1" Margin="5" FontSize="10" Foreground="Red" HorizontalAlignment="Center" /> 
         <Label x:Name="WaveType1" Content="Wave Type:" HorizontalAlignment="Center" Margin="0,10,0,0" /> 
         <ComboBox Margin="10,0" IsReadOnly="True" IsEditable="True" Text="Please select" HorizontalAlignment="Center" > 
          <ComboBoxItem x:Name="ao1wt1" Content="Sine" HorizontalAlignment="Left" Width="198" Selected="ao1wt1_Selected" /> 
          <ComboBoxItem x:Name="ao1wt2" Content="Sawtooth" HorizontalAlignment="Left" Width="198" Selected="ao1wt2_Selected"/> 
          <ComboBoxItem x:Name="ao1wt3" Content="Triangle" HorizontalAlignment="Left" Width="198" Selected="ao1wt3_Selected"/> 
          <ComboBoxItem x:Name="ao1wt4" Content="DC Value" HorizontalAlignment="Left" Width="198" Selected="ao1wt4_Selected"/> 
         </ComboBox> 
         <Grid x:Name="Signal1Params" Margin="0,0,0,10" Visibility="Hidden" > 
          <StackPanel> 
           <Label x:Name="lb_ao1sp1" Content="Frequency:" Margin="0,5,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" /> 
           <StackPanel Orientation="Horizontal" Margin="0" HorizontalAlignment="Center"> 
            <TextBox x:Name="txt_ao1sp1" Text="" Width="50" Height="20" BorderThickness="1,1,0,1" Margin="0,5,0,5" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" /> 
            <Label Content="Hz" Width="25" BorderThickness="0,1,1,1" Margin="0" HorizontalAlignment="Right" Height="20" Padding="0" BorderBrush="#FFABADB3" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" /> 
           </StackPanel> 
           <TextBlock x:Name="tb_no_an_freq1" Margin="5,5,5,0" FontSize="10" Foreground="Red" HorizontalAlignment="Center" /> 
           <Label x:Name="lb_ao1sp2" Content="Offset:" Margin="0,5,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" /> 
           <StackPanel x:Name="ao1sp2" Orientation="Horizontal" Margin="0" HorizontalAlignment="Center"> 
            <TextBox x:Name="txt_ao1sp2" Text="" Width="50" Height="20" BorderThickness="1,1,0,1" Margin="0,5,0,5" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" /> 
            <Label Content="deg" Width="25" BorderThickness="0,1,1,1" Margin="0" HorizontalAlignment="Right" Height="20" Padding="0" BorderBrush="#FFABADB3" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" /> 
           </StackPanel> 
           <TextBlock x:Name="tb_no_an_offset1" Margin="5,5,5,0" FontSize="10" Foreground="Red" HorizontalAlignment="Center" /> 
           <Label x:Name="lb_ao1sp3" Content="Bias:" Margin="0,5,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" /> 
           <StackPanel Orientation="Horizontal" Margin="0" HorizontalAlignment="Center"> 
            <TextBox x:Name="txt_ao1sp3" Text="" Width="50" Height="20" BorderThickness="1,1,0,1" Margin="0,5,0,5" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" /> 
            <Label Content="V" Width="25" BorderThickness="0,1,1,1" Margin="0" HorizontalAlignment="Right" Height="20" Padding="0" BorderBrush="#FFABADB3" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" /> 
           </StackPanel> 
           <TextBlock x:Name="tb_no_an_bias1" Margin="5,5,5,0" FontSize="10" Foreground="Red" HorizontalAlignment="Center" /> 
           <CheckBox x:Name="Signal_Period1" Content="One-Shot Period" HorizontalAlignment="Center" Margin="0,5,0,0" /> 
          </StackPanel> 
         </Grid> 
        </StackPanel> 
       </Grid> 
      </Grid> 
     </TabItem> 
     <TabItem Header="Tab2"> 
      <Grid x:Name="tab2"> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="Auto"/> 
        <RowDefinition /> 
       </Grid.RowDefinitions> 
       <ComboBox x:Name="cob_Add" Height="32" VerticalAlignment="Top" Width="150" HorizontalAlignment="Left" UseLayoutRounding="True" SelectedIndex="-1" Text="Add New Column" IsEditable="True" IsReadOnly="True" Margin="50,0,0,0"> 
        <ComboBoxItem x:Name="cob_Add1" Selected="cob_Add1_Selected" Content="Column1" /> 
        <ComboBoxItem x:Name="cob_Add2" Selected="cob_Add2_Selected" Content="Column2" /> 
        <ComboBoxItem x:Name="cob_Add3" Selected="cob_Add3_Selected" Content="Column3" /> 
       </ComboBox> 
       <ComboBox x:Name="cob_Remove" Height="32" VerticalAlignment="Top" Width="150" HorizontalAlignment="Right" UseLayoutRounding="True" SelectedIndex="-1" Text="Remove Column" IsEditable="True" IsReadOnly="True" Margin="0,0,50,0"> 
        <ComboBoxItem x:Name="cob_Remove1" Selected="cob_Remove1_Selected" Content="Column1" /> 
        <ComboBoxItem x:Name="cob_Remove2" Selected="cob_Remove2_Selected" Content="Column2" /> 
        <ComboBoxItem x:Name="cob_Remove3" Selected="cob_Remove3_Selected" Content="Column3" /> 
       </ComboBox> 
       <Grid x:Name="newcolumns" Grid.Row="1"/> 
      </Grid> 
     </TabItem> 
    </TabControl>  
</Grid> 

code Modifié Derrière:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.IO; 
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.Markup; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Xml; 

namespace WpfApp1 
{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window 
{ 
    public ObservableCollection<DataElement> MyList { get; set; } 
    public ObservableCollection<int> ComboBoxItems { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
     this.ComboBoxItems = new ObservableCollection<int>() { 1, 2, 3 }; 
     this.MyList = new ObservableCollection<DataElement>(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Button btn = sender as Button; 
     DataElement dataContext = btn.DataContext as DataElement; 
     //tab2.Background = Brushes.Red;// do something here <------ 
     //btn.Click += btn1_Click; 

    } 

    //private void btn1_Click(object sender, RoutedEventArgs e) 
    //{ 
    // tab2.Background = Brushes.Red; 
    //} 

    //private void btn2_Click(object sender, RoutedEventArgs e) 
    //{ 
    // tab2.Background = Brushes.Green; 
    //} 

    private void cob_Add_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     ComboBox cb = sender as ComboBox; 
     int? comboBoxItemDataContext = cb.SelectedItem as int?; 

     this.MyList.Add(new DataElement() { Label1 = "Output" + comboBoxItemDataContext.ToString(), Text1 = "", ButtonName = "btn" + comboBoxItemDataContext.ToString(), IsChecked = true }); 
    } 

    private void aol1_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
    { 
     //some code 
    } 
    private void aot1_KeyDown(object sender, KeyEventArgs e) 
    { 
     //some code 
    } 
    private void aot1_LostFocus(object sender, RoutedEventArgs e) 
    { 
     //some code 
    } 
    private void ao1enable_Unchecked(object sender, RoutedEventArgs e) 
    { 
     //some code 
    } 
    private void a1_init() 
    { 
     //some code 
    } 
    private void ao1kickout_Click(object sender, RoutedEventArgs e) 
    { 
     //if (ao1enable.IsChecked == true) 
     //{ 
     // an1kick(); 
     //} 
    } 
    private void an1kick() 
    { 
     //a1_init(); 
     //some code 
    } 
    private void ao1wt1_Selected(object sender, RoutedEventArgs e) 
    { 
     //some code 
    } 
    private void ao1wt2_Selected(object sender, RoutedEventArgs e) 
    { 
     //some code 
    } 
    private void ao1wt3_Selected(object sender, RoutedEventArgs e) 
    { 
     //some code 
    } 
    private void ao1wt4_Selected(object sender, RoutedEventArgs e) 
    { 
     //some code 
    } 
    public class DataElement 
    { 
     public string Label1 { get; set; } 
     public string Text1 { get; set; } 
     public string ButtonName { get; set; } 
     public bool IsChecked { get; set; } 
    } 

} 
+0

émetteur coulé dans votre objet de colonne alors vous ne devriez avoir besoin d'une méthode – 0x4f3759df

+0

je recommande de changer approchez et utilisez _DataTemplate_ing. Recherche le sur Google. – Ron

+0

@Patrick Pouvez-vous être plus précis sur ce dont vous parlez? Je suis nouveau sur WPF et C#, et j'ai besoin d'aide. Je copie le StackPanel de la première colonne de la première tabulation, qui contient les commandes (boutons etc.). Comment puis-je "référencer" le ClickEvent du (nouveau) bouton dans le nouveauStack (Clone), afin qu'il ait le même ClickEvent que le Bouton dans la pile d'origine? – ChrisIo

Répondre

0
<Window x:Class="WpfApp1.MainWindow" 
     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="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <TabControl x:Name="tabControl"> 

      <TabItem Header="Tab2"> 
       <Grid x:Name="tab2"> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition /> 
        </Grid.RowDefinitions> 
        <ComboBox 
         x:Name="comboBox" 
         Height="32" 
         VerticalAlignment="Top" 
         Width="150" 
         HorizontalAlignment="Left" 
         UseLayoutRounding="True" 
         SelectedIndex="-1" 
         Text="Add New Column" 
         IsEditable="True" 
         IsReadOnly="True" 
         Margin="50,0,0,0" 
         SelectionChanged="cob_Add_SelectionChanged" 
         ItemsSource="{Binding ComboBoxItems}" 
         /> 

        <ListBox Width="400" ItemsSource="{Binding MyList}" Grid.Row="1" x:Name="Test"> 
         <ListBox.ItemTemplate> 
          <DataTemplate> 
           <StackPanel> 
            <Label Content="{Binding Label1}" /> 
             <TextBox Text="{Binding Text1}" /> 
             <Button Content="{Binding ButtonName}" Click="Button_Click"/> 
             <CheckBox IsChecked="{Binding IsChecked}" /> 
            </StackPanel> 
          </DataTemplate> 
         </ListBox.ItemTemplate> 
        </ListBox> 

       </Grid> 
      </TabItem> 
     </TabControl> 
    </Grid> 
</Window> 


using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.IO; 
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.Markup; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Xml; 

namespace WpfApp1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public ObservableCollection<DataElement> MyList { get; set; } 
     public ObservableCollection<int> ComboBoxItems { get; set; } 

     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
      this.ComboBoxItems = new ObservableCollection<int>() { 1, 2, 3 }; 
      this.MyList = new ObservableCollection<DataElement>(); 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      Button btn = sender as Button; 
      DataElement dataContext = btn.DataContext as DataElement; 
      // do something here <------ 
     } 

     private void cob_Add_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      ComboBox cb = sender as ComboBox; 
      int? comboBoxItemDataContext = cb.SelectedItem as int?; 

      if (comboBoxItemDataContext == 1) 
      { 
       this.MyList.Add(new DataElement() { Label1="1", Text1 = "1", ButtonName = "1", IsChecked = true }); 
      } 
      if (comboBoxItemDataContext == 2) 
      { 
       this.MyList.Add(new DataElement() { Label1 = "2", Text1 = "2", ButtonName = "2", IsChecked = true }); 
      } 
      if (comboBoxItemDataContext == 3) 
      { 
       this.MyList.Add(new DataElement() { Label1 = "3", Text1 = "3", ButtonName = "3", IsChecked = true }); 
      } 
     } 
    } 

    public class DataElement 
    { 
     public string Label1 { get; set; } 
     public string Text1 { get; set; } 
     public string ButtonName { get; set; } 
     public bool IsChecked { get; set; } 
    } 

} 
+0

Tout d'abord, merci pour votre aide! J'ai modifié mon exemple de code ci-dessus et ajouté une colonne telle qu'elle est dans ma vraie application. Si je comprends bien, à partir de votre solution, je dois créer, pour chaque élément de ma colonne, un nouvel élément et "transférer" ses propriétés à nouveau. N'est-ce pas trop de code? Je veux dire que je veux: 1. sélectionner, dans la comboBox, quelle colonne copier 2. tous les éléments de la colonne ont les mêmes propriétés et les mêmes événements que les éléments d'origine, sans redéfinir leur taille, clickevents, etc. Peut-être que je n'ai pas t comprendre votre solution correctement. – ChrisIo

+0

@ChrisIo Vous devriez exécuter ma solution jusqu'à ce que vous compreniez ce qu'il fait. Je pense que cela changera d'avis sur le transfert de propriétés. Regardez aussi dans UserControls. Ensuite, vous pourriez hypothétiquement dire Grid.Children.Add (new UserControl()) et obtenir une nouvelle copie de vos contrôles avec les boutons branchés – 0x4f3759df