2017-05-09 115 views
0

纠正我,如果有这样做的更好的办法:)访问产生的UI元素代码

我要补充UIElement(在我的情况StackPanel)动态我的XAML。

我的代码:

foreach (Dienstleistung dienstleistung in dienstleistungenList) 
{ 
    var xaml = System.Windows.Markup.XamlWriter.Save(StackPanelTemplate); 
    var deepCopy = System.Windows.Markup.XamlReader.Parse(xaml) as StackPanel; 
    foreach (UIElement child in deepCopy.Children) 
    { 
     if (child is TextBlock) 
     { 
      var y = child as TextBlock; 
      switch (y.Text) 
      { 
       case "Titel": 
        y.Text = dienstleistung.Title; 
        break; 
       case "Beschreibung": 
        y.Text = dienstleistung.Summary; 
        break; 
      } 
     } 
    } 
    MainContainer.Children.Add(deepCopy); 
} 

的XAML:

<WrapPanel Name="MainContainer" HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <StackPanel Name="StackPanelTemplate" Margin="5px" Width="200px" MouseLeftButtonUp="StackPanelOnClick"> 
      <StackPanel.Style> 
       <Style> 
        <Setter Property="Border.Background" Value="LightCyan"/> 
        <Style.Triggers> 
         <Trigger Property="Border.IsMouseOver" Value="True"> 
          <Setter Property="Border.Background" Value="LightGreen" /> 
         </Trigger> 
        </Style.Triggers> 
       </Style> 
      </StackPanel.Style> 
      <Image Margin="5px" Width="190px" Height="190px"></Image> 
      <TextBlock TextAlignment="Center" TextWrapping="WrapWithOverflow" Margin="5px" FontSize="16">Titel</TextBlock> 
      <TextBlock TextAlignment="Center" TextWrapping="WrapWithOverflow" Margin="5px">Beschreibung</TextBlock> 
      <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 
       <TextBox x:Name="txtNum" x:FieldModifier="private" Margin="5,5,0,5" Width="50" Text="0" TextChanged="txtNum_TextChanged" /> 
       <Button x:Name="cmdUp" x:FieldModifier="private" Margin="5,5,0,5" Content="˄" Width="20" Click="cmdUp_Click" /> 
       <Button x:Name="cmdDown" x:FieldModifier="private" Margin="0,5,0,5" Content="˅" Width="20" Click="cmdDown_Click" /> 
      </StackPanel> 
     </StackPanel> 
    </WrapPanel> 

总之,我有一个模板,我复制它。

现在我有一个TextBox在我的模板中,我有一个TextChanged事件。现在我的问题是,为什么这个事件不会触发?有没有办法访问这些生成的元素?

+2

丢弃所有代码并仔细阅读MSDN上的[数据模板概述](https://msdn.microsoft.com/en-us/library/ms742521.aspx)文章。然后使用ObservableCollection的Dienstleistung项目创建一个视图模型,并将ListBox的ItemsSource属性绑定到该集合。在ListBox的ItemTemplate中,声明TextBoxes并将其Text属性绑定到相应的Dienstleistung属性。 – Clemens

回答

0

根据微软的Serialization Limits of XamlWriter.Save在序列化过程中事件处理不会被保留。如果你仔细想一想,原因应该是显而易见的。即使它能以某种方式认识到附加到该事件的对象是一个控件,它可以序列化并进一步识别它已经序列化一个组件以避免无限循环,但是当它被反序列化时会发生什么?您当然不会将TextChanged事件挂钩到已经存在的完全相同的对象上......它必须创建控制的另一个实例,后面的代码被实现并附加到它,因为它无法知道关于已经在记忆中的那个。

幸运的是,有一个更好的方法可以实现你想要做的事情。在WPF中,当您想要在某种列表上重复一个可变数量的控件时,您需要使用ItemsControl或其派生项之一来查看。如果将项目列表绑定到ItemsSource依赖项属性,然后将所需控件置于ItemTemplate中的每个项目上,则框架将为列表中的每个项目创建一个新实例,将其设置为ItemsControl,并将新创建的控件的DataContext设置为它为其创建的列表中的项目。移动你的XAML张望了一下,它最终会看起来像这样:

<ItemsControl ItemsSource="{Binding DienstleistungenList}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <WrapPanel HorizontalAlignment="Center" VerticalAlignment="Center" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Name="StackPanelTemplate" 
         Width="200px" 
         Margin="5px" 
         MouseLeftButtonUp="StackPanelOnClick"> 
       <StackPanel.Style> 
        <Style> 
         <Setter Property="Border.Background" Value="LightCyan" /> 
         <Style.Triggers> 
          <Trigger Property="Border.IsMouseOver" Value="True"> 
           <Setter Property="Border.Background" Value="LightGreen" /> 
          </Trigger> 
         </Style.Triggers> 
        </Style> 
       </StackPanel.Style> 
       <Image Width="190px" 
         Height="190px" 
         Margin="5px" /> 
       <TextBlock Margin="5px" 
          FontSize="16" 
          Text="{Binding Title}" 
          TextAlignment="Center" 
          TextWrapping="WrapWithOverflow" /> 
       <TextBlock Margin="5px" 
          Text="{Binding Summary}" 
          TextAlignment="Center" 
          TextWrapping="WrapWithOverflow" /> 
       <StackPanel HorizontalAlignment="Center" 
          VerticalAlignment="Center" 
          Orientation="Horizontal"> 
        <TextBox x:Name="txtNum" 
          Width="50" 
          Margin="5,5,0,5" 
          x:FieldModifier="private" 
          Text="0" 
          TextChanged="txtNum_TextChanged" /> 
        <Button x:Name="cmdUp" 
          Width="20" 
          Margin="5,5,0,5" 
          x:FieldModifier="private" 
          Click="cmdUp_Click" 
          Content="˄" /> 
        <Button x:Name="cmdDown" 
          Width="20" 
          Margin="0,5,0,5" 
          x:FieldModifier="private" 
          Click="cmdDown_Click" 
          Content="˅" /> 
       </StackPanel> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

正如在评论中有人建议,我会建议你阅读Data Templating Overview也将添加Data Binding Overview因为这两个是关键了解如何编写基于XAML的应用程序。

+0

谢谢。你帮了我很多:D – Lotok