2015-12-07 3 views
0

Я создаю динамический графический интерфейс для обучения. После нажатия кнопки «+» пользователь может добавить шаблон itemControl.Адрес динамически созданного контента в wpf C#

Какова наилучшая практика получения элемента по имени (в данном случае x: Name = "lblName", который должен быть доступен, но должен быть создан первым) динамически созданных элементов?

MainWindow.xaml:

<ItemsControl Name="icDynamicTableColumn"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Grid Margin="0,0,0,5"> 
        <StackPanel> 
         <TextBlock Text="{Binding Description}" Height="23" Width="auto" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5"/> 
         <TextBox x:Name="lblName" Text="{Binding Textfield}" Height="23" VerticalAlignment="Top" HorizontalAlignment="Stretch" Margin="5"/> 
        </StackPanel> 
       </Grid> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

MainWindow.xaml.cs:

public partial class MainWindow : Window 
{ 
     [...] 
     public ObservableCollection<DynamicTableColumn> items = new ObservableCollection<DynamicTableColumn>(); 
     [...] 

     public MainWindow() 
     { 
       [...] 
       InitializeComponent(); 
       icDynamicTableColumn.ItemsSource = items; 
     } 

     public class DynamicTableColumn 
     { 
       public string Description 
       { 
         get { 
           return _description; 
         } 

         set { 
           [...] 
         } 
       } 
       private string _description; 
       public string Textfield { get; set; } 
     } 

} 
+0

Я не уверен, чего вы хотите достичь? Вы хотите получить Имя или Элемент, который имеет это имя? – LionAM

+0

Очистить: обработать динамически созданный объект для доступа к методам. – SimpleMath

+0

Существует несколько способов, однако все не так просто (поскольку ItemsControl не предоставляет метод для получения (визуального) контейнера для элемента). Что вы хотите достичь, если у вас есть TextBox? Было бы достаточно, чтобы вас уведомили, изменит ли пользователь текст? – LionAM

ответ

0

Если это достаточно, чтобы сделать какую-то операцию, когда пользователь добавляет новый элемент или изменяет текст, я бы предлагать использовать события, например Loaded или TextChanged.

Если вам действительно нужно найти текстовое поле динамически, можно использовать следующий код:

ObservableCollection<DynamicTableColumn> Collection = new ObservableCollection<DynamicTableColumn>(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     icDynamicTableColumn.ItemsSource = Collection; 

     Loaded += MainWindow_Loaded; 
    } 

    private StackPanel Panel; 

    private void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     //find the panel that contains the children 
     Panel = (StackPanel)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(
       VisualTreeHelper.GetChild(icDynamicTableColumn, 0), 0), 0); 
    } 

    TextBox GetTextBoxForIndex(int index) 
    { 
     //get the child for a given index 
     var presenter = (ContentPresenter)VisualTreeHelper.GetChild(Panel, index); 
     return (TextBox)presenter.ContentTemplate.FindName("lblName", presenter); 
    } 

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
    { 
     Collection.Add(new DynamicTableColumn()); 
     //make sure that the Textbox was loaded 
     icDynamicTableColumn.UpdateLayout(); 

     var textBox = GetTextBoxForIndex(Collection.Count - 1); 
    } 

Просто надо знать, что это предполагает, что вы используете ItemsControl и не изменить его (Control) Шаблон. Если вам часто приходится это делать, вы можете создать свой собственный элемент ItemsControl (получить от него) и выставить метод GetTextBoxForIndex. Однако вы должны выполнить некоторые проверки безопасности (например, индекс в диапазоне и презентатор должен быть загружен).

Смежные вопросы