【问题标题】:Add to StackPanel DataTemplate instances programatically -WPF以编程方式添加到 StackPanel DataTemplate 实例 -WPF
【发布时间】:2015-01-12 12:31:25
【问题描述】:

假设我在 XAML 中有 WPF 视图:

<Window x:Class="TestingMatrix.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestingMatrix"

    Title="All Learned Numbers" Height="500" Width="800">


    <Window.Resources>
        <!--Defining a dataTemplate-->
    <DataTemplate x:Key="myTaskTemplate"  DataType="{x:Type local:LearnedElement}">
        <StackPanel>
                <Label Content="Input:" Margin="8,6,-320,-164"  />
                <TextBlock Text="{Binding Path=InputTxt}" HorizontalAlignment="Left" Margin="56,9,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Height="48" Width="300"/>
                <Label Content="Output:" HorizontalAlignment="Left" Margin="378,9,0,0" VerticalAlignment="Bottom"/>
                <TextBlock Text="{Binding Path=OutputTxt}"  HorizontalAlignment="Left" Margin="444,9,0,0" TextWrapping="Wrap"  VerticalAlignment="Top" Height="48" Width="295"/>
                <DataGrid Name="myDataGrid" CanUserAddRows="False" CanUserResizeRows="False"      Margin="44,66,0,0" CanUserDeleteRows="False" Focusable="False" AreRowDetailsFrozen="True" IsEnabled="False" CanUserReorderColumns="False"  HorizontalAlignment="Left"  VerticalAlignment="Top"  HeadersVisibility="None"/>
                <DataGrid Name="myDataGrid_Copy" CanUserAddRows="False" CanUserResizeRows="False" Margin="445,66,0,0" CanUserDeleteRows="False" Focusable="False" AreRowDetailsFrozen="True" IsEnabled="False" CanUserReorderColumns="False"  HorizontalAlignment="Left"  VerticalAlignment="Top"  HeadersVisibility="None"/>       
            </StackPanel>
        </DataTemplate>


    </Window.Resources>

    <Grid Height="500" Width="800" Name="myGrid">
         <!--Place a dataTemplate instance in here, it will get the values from a list of elements -->
    <ListBox ItemsSource="{Binding ObservableElements}">

    </ListBox>

    </Grid>

</Window>

我有一个类来表示 Observable 集合列表中的每个项目。

public class LearnedElement 
{
      public string InputTxt {get; set;}
      public string OutputTxt {get; set;}
}

我有代码隐藏:

       //List of elements that will be binded with the template
       public ObservableCollection<LearnedElement> observableElements { get; set; }

        public Window2()
        {

            InitializeComponent();

            ObservableElements = new ObservableCollection<LearnedElement>();

            LearnedElement learnedElem = new LearnedElement();
            learnedElem.InputTxt = "Example 1";
            learnedElem.OutputTxt = "Example 2";

            //How to create an instance of the template and add to the StackPanel ?

            LearnedElement learnedElem2 = new LearnedElement();
            learnedElem2.InputTxt = "Example 3";
            learnedElem2.OutputTxt = "Example 4";

            ObservableElements.Add(learnedElem);
            this.DataContext = ObservableElements;
        }

我想最终得到类似于下面绘制的东西,从元素列表中我将实例化一个新的 DataTemplate 并将其放置在 StackPanel 上:

最好的方法是什么?

已编辑,但仍无法正常工作:

将 StackPanel 更改为 ListBox

【问题讨论】:

  • 使用 ItemsControl - msdn.microsoft.com/en-us/library/…
  • 是的 ItemControl 是要走的路,但要小心,因为 ItemControl 默认不支持选择。但是,您可以创建自己的 ItemControl 来实现 ISelectable
  • 您应该在您的DataTemplate 上设置您的TargetType="{x:Type LearnedElement}" 或将模板放入StackPanel 模板中,就像这样&lt;StackPanel.Template&gt;&lt;DataTemplate&gt;&lt;Label Content="Input:" Margin="8,6,-320,-164"/&gt; ... &lt;/StackPanel.Template&gt;
  • @Franck “创建您自己的实现 ISelectable 的 ItemControl”。什么?需要选择时使用 ListBox(它是一个 ItemsControl)。
  • @Clemens 是的,但这取决于他是否需要将孩子包裹在容器中。 ListBox 将换行,但ItemControl 不会。 No Select -&gt; ItemControl, Select + Wrap -&gt; ListBox, Select + No Wrap -&gt; ItemControl + ISelectable

标签: c# wpf data-binding datatemplate


【解决方案1】:

使用ListBox 而不是StackPanel,只需将您的集合项数据绑定到它的ItemsSource 属性:

<ListBox ItemsSource="{Binding YourCollectionProperty}" />

当然,您需要声明YourCollectionProperty 属性:

// Implement the INotifyPropertyChanged interface on this property:
public ObservableCollection<LearnedElement> YourCollectionProperty { get; set; }

最后,将您的项目直接添加到集合属性中:

...
YourCollectionProperty.Add(local:learnedElem);

您添加的每个项目都将出现在ListBox 中。哦,最后一件事......像这样声明您的DataTemplate,以便框架在看到您的对象时知道使用它:

<DataTemplate DataType="{x:Type LearnedElement}"> 
    ...
</DataTemplate>

【讨论】:

  • 嗨@Sherindan,我稍微改变了你的答案,有些属性不存在,但仍然不起作用,没有显示任何东西......
  • 谢谢@Tito,但如果你看,你会发现社区拒绝了你的编辑......我猜是因为你试图改变太多并添加了你自己的错误。最好将编辑更改保持在必要的范围内。我现在自己修复了错误。
  • 感谢@Sheridan 的提示 :)
猜你喜欢
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 2016-01-05
相关资源
最近更新 更多