【问题标题】:WPF Data binding to observableCollectionWPF 数据绑定到 observableCollection
【发布时间】:2014-11-18 21:15:00
【问题描述】:

有人可以帮我解决这个问题吗 我正在尝试将应用程序重组为 MVVM 并更好地利用数据绑定,但遇到了一个小问题。

我有一个视图模型类

public class MainWindowViewModel
{
    public ObservableCollection<DiagramElement> Elements { get; set; }


    public MainWindowViewModel()
    {
        AppMachineList = new ListOfMachines();
        Elements = new ObservableCollection<DiagramElement>();
    } 
}

我在其中创建了 DiagramElement 类的 observablecollection。

public class DiagramElement : Button
{
    private Item linkedItem;

    public Item LinkedItem
    {
        get { return this.linkedItem; }
        set
        {
            this.linkedItem = value;
            this.DataContext = this;
            this.Template = (ControlTemplate)FindResource("ItemTemplate");

        }
    }

DiagramElement 类只是扩展了按钮类并添加了自己的 controlTemplate。

回到我的 MainWindow.xaml.cs 类,我实例化视图模型,然后从 ObservableCollection 填充 MainWindow.xaml 中的堆栈面板。

public partial class MainWindow 
{
    public MainWindow()
    {

        InitializeComponent();
        MainWindowViewModel vm = new MainWindowViewModel();
        vm.LoadMachines();

        foreach(DiagramElement d in vm.Elements)
        {
            ItemList.Children.Add(d);
        }

    }
}

<StackPanel x:Name="ItemList" Orientation="Vertical"></StackPanel>

我想要做的是,取消 foreach 循环和对 ItemList.Children.Add() 的调用。并将其替换为与视图模型中元素的绑定,如下所示。

public partial class MainWindow 
{
    public MainWindow()
    {

        InitializeComponent();
        MainWindowViewModel vm = new MainWindowViewModel();
        vm.LoadMachines();

        this.DataContext = vm;

    }
}

<StackPanel x:Name="ItemList" DataContext="{Binding Path=Elements}"</Stackpanel>

我无法将要添加到 Stackpanel 的元素,绑定不起作用。感谢您提供任何帮助。

【问题讨论】:

  • 你误解了 MVVM 的概念。 UI 的东西不应该出现在 ViewModel 中。它仅用于保存数据而不是 UI 控件(在您的情况下为按钮)。
  • 是的,这些按钮最初是在 MainWindow 中创建的。我试图解决一些问题并将它们移到视图模型中。感谢您的回复。

标签: wpf data-binding


【解决方案1】:

仅供参考,拥有一个带有 UI 元素(在您的情况下是按钮)集合的 ViewModel 违反了 MVVM 的原则——UI 和模型不应该像这样混合在一起。

但最直接的问题是您不能使用 StackPanel——它是一个控制容器,但不支持绑定到项目列表。您需要使用某种中继器,例如 ItemsControl。

<ItemsControl ItemsSource="{Binding Path=Elements}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <!-- your DiagramElement should go here, something like
      <DiagramElement LinkedItem={Binding Path=SomePropertyOnYourRevisedElement} />
      -->
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

但还有更多工作要做。 DiagramElement 需要将LinkedItem 转换为DependencyProperty(网上有很多这样的例子)和Elements 需要是某种模型对象的列表,它只存储DiagramElement 所需的属性(没有用户界面的东西)。

【讨论】:

  • 您好 Paul,感谢您的回复,已经完成了与您在之前项目中的建议类似的操作,我想我可能过于复杂了。是的,我打算从视图模型中删除 UI 集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 2013-04-18
  • 2013-12-30
  • 2011-06-06
  • 2014-05-25
  • 2017-09-29
  • 1970-01-01
相关资源
最近更新 更多