使用MVVM结构复制TabItem

时间:2013-09-04 20:11:33

标签: c# wpf mvvm tabitem

这是尝试扩展this question。在我的WPF计划中,我在名为tabItems的函数中使用XamlWriter克隆了TrycloneElement。我最初找到了这个函数here,但也可以在上一个问题的链接中查看该函数。

现在我开始担心程序中的功能,我发现TrycloneElement函数不会复制分配给它正在克隆的tabItem的任何代码隐藏功能。

由于High Core的链接和对我之前问题的评论,我决定通过使用我的ViewModel的数据绑定开始在我的tabItems上实现功能。

以下是我实施的命令示例:

public viewModel()
{
    allowReversing = new Command(allowReversing_Operations);
}

public Command AllowReversing
{
       get { return allowReversing; }
} 

private Command allowReversing; 

private void allowReversing_Operations()
{
       //Query for Window1
       var mainWindow = Application.Current.Windows
           .Cast<Window1>()
           .FirstOrDefault(window => window is Window1) as Window1;

       if (mainWindow.checkBox1.IsChecked == true) //Checked
       {
           mainWindow.checkBox9.IsEnabled = true;
           mainWindow.groupBox7.IsEnabled = true;
       }
       else //UnChecked
       {
           mainWindow.checkBox9.IsEnabled = false;
           mainWindow.checkBox9.IsChecked = false;
           mainWindow.groupBox7.IsEnabled = false;
       }
} 

*注意:我知道我在上面的代码中直接与我的View进行了欺骗和交互,但我不确定如何运行这些命令。如果这是一个问题,或者有另一种方法,请告诉我如何运行这些相同的命令而不像我那样与View交互。

现在回答问题:

更改我的代码并将命令添加到我的ViewModel后,TrycloneElement功能不再有效。在选项卡克隆期间的运行时,我收到XamlParseException在线object x = XamlReader.Load(xmlReader);,其中显示: enter image description here

如果有更好的方法而且我不再需要它,我就放弃了这个功能。但最终,我如何采用tabItem的设计和功能并克隆它? (请记住,我真的想要纠正我的结构)

感谢您的帮助。

修改Leo的回答

这是我编译的Leo答案的当前版本。 (有一些语法错误)

public static IList<DependencyProperty> GetAllProperties(DependencyObject obj)
{
       return (from PropertyDescriptor pd in TypeDescriptor.GetProperties(obj, new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.SetValues) })
                    select DependencyPropertyDescriptor.FromProperty(pd)
                   into dpd
                   where dpd != null
                   select dpd.DependencyProperty).ToList();
}

public static void CopyPropertiesFrom(this FrameworkElement controlToSet,
                                                   FrameworkElement controlToCopy)
{
       foreach (var dependencyValue in GetAllProperties(controlToCopy)
                    .Where((item) => !item.ReadOnly)
                    .ToDictionary(dependencyProperty => dependencyProperty, controlToCopy.GetValue))
       {
           controlToSet.SetValue(dependencyValue.Key, dependencyValue.Value);
       }
}

2 个答案:

答案 0 :(得分:1)

1。)要修复XamlParseException,请确保您有一个像空的公共构造函数,您可能已经定义了一个构造函数,当您尝试序列化该对象并反序列化时,它不能。您必须显式添加默认构造函数。

2。)我不喜欢克隆这个词,但是我想说,当他们想要复制时。我将手动创建一个新的标签项控件,然后对其进行反射。

我有这个代码,我做了

  public static IList<DependencyProperty> GetAllProperties(DependencyObject obj)
    {
        return (from PropertyDescriptor pd in TypeDescriptor.GetProperties(obj, new Attribute[] {new PropertyFilterAttribute(PropertyFilterOptions.SetValues)})
                select DependencyPropertyDescriptor.FromProperty(pd)
                into dpd where dpd != null select dpd.DependencyProperty).ToList();
    }


    public static void CopyPropertiesFrom(this FrameworkElement controlToSet,
                                               FrameworkElement controlToCopy)
    {
        foreach (var dependencyValue in GetAllProperties(controlToCopy)
                .Where((item) => !item.ReadOnly))
                .ToDictionary(dependencyProperty => dependencyProperty, controlToCopy.GetValue))
        {
            controlToSet.SetValue(dependencyValue.Key, dependencyValue.Value);
        }
    }

所以它会像

var newTabItem = new TabItem();
newTabItem.CopyPropertiesFrom(masterTab);

答案 1 :(得分:1)

Here是我在WPF中正确实施的动态TabControl的示例。

主要思想是每个Tab项是一个单独的小部件,包含自己的逻辑和数据,由ViewModel处理,而UI执行UI必须执行的操作:show数据,而不是{{ 1}}数据。

最重要的是,所有数据和功能都在ViewModel / Model级别进行管理,并且由于contain绑定到TabControl,因此您只需在需要时向该集合添加另一个元素添加新标签。

这样就无需“克隆”UI或使用它进行任何其他奇怪的操作。