0

这是对这个问题的扩展尝试。在我的 WPF 程序中,我一直在tabItems使用一个XamlWriter名为TrycloneElement. 我最初是在这里找到这个功能的,但是这个功能也可以在我上一个问题的链接中查看。

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

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

这是我实现的命令示例:

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;
       }
} 

*注意:我知道我在上面的代码中作弊并直接与我的视图交互,但我不确定如何运行这些命令。如果这是一个问题,或者有其他方法,请告诉我如何在不与视图交互的情况下运行这些相同的命令。

现在的问题:

更改我的代码并将命令添加到我的 ViewModel 后,该TrycloneElement功能不再起作用。在选项卡克隆期间运行时,我收到一条XamlParseException在线消息,object x = XamlReader.Load(xmlReader);内容如下: 在此处输入图像描述

如果有更好的方法并且我不再需要它,我可以放弃该功能。但最终,我如何获取 atabItem的设计和功能并克隆它?(请记住,我真的在尝试纠正我的结构)

谢谢您的帮助。

修改 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);
       }
}
4

2 回答 2

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);
于 2013-09-04T20:31:17.830 回答
1

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

主要思想是,每个 Tab Item 都是一个单独的小部件,包含自己的逻辑和数据,由 ViewModel 处理,而 UI 执行 UI 必须做的事情:show数据,而不是contain数据。

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

这消除了“克隆” UI 或对其进行任何其他奇怪操作的需要。

于 2013-09-04T21:42:00.867 回答