这是尝试扩展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);
,其中显示:
如果有更好的方法而且我不再需要它,我就放弃了这个功能。但最终,我如何采用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);
}
}
答案 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或使用它进行任何其他奇怪的操作。