使用MVVM以编程方式使用用户控件的observablecollection填充stackpanel

使用MVVM以编程方式使用用户控件的observablecollection填充stackpanel,mvvm,controls,observablecollection,stackpanel,Mvvm,Controls,Observablecollection,Stackpanel,我有一个类型为frameworkelement的observablecollection,我想在stackpanel或类似的东西中显示它。observablecollection中的每个项都是我创建的usercontrol。我是WPF的新手,我不知道怎么做。请举一个例子使用ItemsControl绑定StackPanel中的ObservableCollection: 视图(xaml): 代码隐藏(xaml.cs): 公共部分类主窗口:窗口 { 公共ObservableCollection

我有一个类型为frameworkelement的observablecollection,我想在stackpanel或类似的东西中显示它。observablecollection中的每个项都是我创建的usercontrol。我是WPF的新手,我不知道怎么做。请举一个例子

使用ItemsControl绑定StackPanel中的ObservableCollection:

视图(xaml):


代码隐藏(xaml.cs):

公共部分类主窗口:窗口
{
公共ObservableCollection ObservableCollection{get;set;}
公共主窗口()
{
初始化ObservableCollection();
初始化组件();
}
私有void InitializeObservableCollection()
{
ObservableCollection=新的ObservableCollection();
对于(var ii=0;ii<10;ii++)
{
添加(新按钮{Content=ii.ToString()});
}
}
}

我在这里借用了rhe1980的答案,但关键是codebehind中的代码实际上将位于viewmodel中

视图:

视图模型:

    public class MyViewModel: INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (!string.IsNullOrEmpty(propertyName))
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        this.OnObjectChanged();
    } 

   private ObservableCollection<FrameworkElement> _myCollection;
   public ObservableCollection<FrameworkElement> MyCollection
    {
        get
        {
            return _myCollection;
        }
        set
        {
            _myCollection = value;
            OnPropertyChanged("MyCollection");
        }
    }     
}
公共类MyViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的无效OnPropertyChanged(字符串propertyName)
{
如果(!string.IsNullOrEmpty(propertyName))
{
if(this.PropertyChanged!=null)
this.PropertyChanged(this,newpropertychangedventargs(propertyName));
}
this.onObject已更改();
} 
私人可观察收集(myCollection);;
公共可观测集合MyCollection
{
得到
{
返回_myCollection;
}
设置
{
_myCollection=value;
关于财产变更(“MyCollection”);
}
}     
}

MVVM通常不赞成这种技术,因为您将viewmodel与视图紧密耦合,导致可测试性、可移植性等降低。这种框架元素的可观察集合来自何处?在一个完美的世界中,viewmodel是一个属性集合,它不关心前端是如何实现的。通过拥有FrameworkElement的observablecollection,您将VM耦合到特定的表示实现。它当然很实用。让我知道下面的答案是否解决了您的问题!:-)你的解决方案很有魅力!谢谢如果您正在使用某种依赖项注入,虚拟机实际上可能会被传递到视图的构造函数中,但是如果需要,我可以添加一个快速修复。
public partial class MainWindow : Window
{
    public ObservableCollection<FrameworkElement> ObservableCollection { get; set; }

    public MainWindow()
    {
        InitializeObservableCollection();
        InitializeComponent();
    }

    private void InitializeObservableCollection()
    {
        ObservableCollection = new ObservableCollection<FrameworkElement>();
        for (var ii = 0; ii < 10; ii++)
        {
            ObservableCollection.Add(new Button {Content = ii.ToString()});
        }
    }
}
<Window x:Class="Sandbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
Name="mainWindow">
<Grid>
<StackPanel>
    <ItemsControl ItemsSource="{Binding Path=MyCollection}"/>                           
</StackPanel>         
</Grid>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MyViewModel();
    }
}
    public class MyViewModel: INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        if (!string.IsNullOrEmpty(propertyName))
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        this.OnObjectChanged();
    } 

   private ObservableCollection<FrameworkElement> _myCollection;
   public ObservableCollection<FrameworkElement> MyCollection
    {
        get
        {
            return _myCollection;
        }
        set
        {
            _myCollection = value;
            OnPropertyChanged("MyCollection");
        }
    }     
}