2017-05-09 97 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