C# 在listbox的ItemTemplate中包含itemsource本身的项

C# 在listbox的ItemTemplate中包含itemsource本身的项,c#,wpf,listbox,itemtemplate,C#,Wpf,Listbox,Itemtemplate,我的WPF应用程序中有一个列表框 <ListBox ItemsSource="{Binding ButtonsCollection}"> <ListBox.ItemTemplate> <DataTemplate> <Border BorderBrush="Black" BorderThickness="2" > **Here I want to insert the

我的WPF应用程序中有一个列表框

 <ListBox ItemsSource="{Binding ButtonsCollection}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="2" >
                **Here I want to insert the current button**
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

**我想在这里插入当前按钮**

在我的viewmodel中,我有一个按钮集合,一个名为ButtonsCollection的属性。 让我们说: 内容为“a”的按钮, 内容为“b”的按钮, 内容为“c”的按钮


现在,我想让列表框显示这些按钮中的每一个,它们都有一个边框,正如我在ItemTemplate中声明的那样。

DataTemplate是为ItemsControl中的每个项目实例化的(在您的例子中是listbox)。它的唯一作用是描述渲染时项目的外观

DataContext应该包含描述UI状态的对象

这是一个分离的关注点。通过这种方式,UI和后端可以由多人独立开发,DataContext就是契约

当然,正如托马斯·克里斯托夫(Thomas Christof)所指出的,该框架不会以任何方式强迫您这样做

如果您这样做:

 <ListBox ItemsSource="{Binding ButtonsCollection}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="2" >
                <ContentControl Content={Binding}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
您可以将同一集合绑定到多个控件,例如菜单栏、上下文菜单、侧面板等

在您的情况下,这是一个列表框:

 <ListBox ItemsSource="{Binding Commands}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="2" >
                <Button Content="{Binding Name}" Command="{Binding}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

另一个问题是,当后台线程试图操纵按钮时,您将使用当前方法遇到。 UI元素与创建它们的线程(STA线程)相关联。 最后,您将在Dispatcher.Invokes中包装所有调用,可能会在某个时刻出现死锁。 但是,实现INotifyPropertyChanged,并在需要时提高PropertyChanged将给WPF框架带来这个负担(更新通知在引擎盖下的主线程上调度)


最后,在代码隐藏中创建UI并不总是一个坏主意。假设您希望在应用程序中实现插件系统,并在布局中保留一个可折叠区域,该区域将承载未知插件的UI。你不能强迫插件的开发者只拥有两个按钮和一个文本框,这样它就能很好地适应你的数据模板。一个好的解决方案是在保留空间中放置ContentControl,并为开发人员提供一个要实现的接口,其中包含一个
object GetUI() 您是否尝试过ContentPresenter Content=“{Binding}”/>”在我的viewmodel中,我有一组按钮”。听起来很奇怪。视图模型中不应该有任何视图元素。相反,应该有一个具有某些属性的item类。然后ItemTemplate将声明一个按钮,该按钮具有绑定到视图模型项属性的属性。
 <ListBox ItemsSource="{Binding Commands}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="2" >
                <Button Content="{Binding Name}" Command="{Binding}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>