我正在尝试向现有库添加新功能.我需要将新数据添加到类层次结构中,以便根类具有访问器.任何人都应该能够获得这些数据,只有子类可以设置它(即公共getter和受保护的setter).
为了保持向后兼容性,我知道我不能执行以下任何操作(列表仅包括与我的问题相关的操作):
我可以想到将这些数据添加到层次结构的两种方法:向根类添加新的成员变量或添加纯虚拟访问器函数(以便可以将数据存储在子类中).但是,为了保持向后的可比性,我不能做其中任何一个.
该库正在广泛使用pimpl成语,但不幸的是我必须修改的根类不使用这个成语.然而,子类使用这个习语.
现在只有我能想到的解决方案是使用静态哈希映射模拟成员变量.所以我可以创建一个静态哈希映射,将这个新成员存储到它,并为它实现静态访问器.像这样(在伪c ++中):
class NewData {...};
class BaseClass
{
protected:
static setNewData(BaseClass* instance, NewData* data)
{
m_mapNewData[instance] = data;
}
static NewData* getNewData(BaseClass* instance)
{
return m_mapNewData[instance];
}
private:
static HashMap<BaseClass*, NewData*> m_mapNewData;
};
class DerivedClass : public BaseClass
{
void doSomething()
{
BaseClass::setNewData(this, new NewData());
}
};
class Outside
{
void doActions(BaseClass* action)
{
NewData* data = BaseClass::getNewData(action);
...
}
};
Run Code Online (Sandbox Code Playgroud)
现在,虽然这个解决方案可能有用,但我发现它非常难看(当然我也可以添加非静态访问器函数,但这不会消除丑陋).
还有其他解决方案吗?
谢谢.
我们正在创建一个WPF应用程序,它大量使用高度装饰的输入元素.一个简单的装饰元素示例是TextBox,它在没有焦点时看起来像只读TextBlock,在接收焦点后变成TextBox.此外,当更改的值保存到数据库时,会提供其他可视反馈.问题是显示包含大量这些元素的视图(假设为100)非常慢并且使应用程序非常无响应.
我们已将此装饰器实现为UserControl,其中包含所有必需元素(例如,TextBlock用于显示未聚焦文本和旋转图像用于忙碌指示符).然后我们将input元素添加为此装饰器控件的子元素,这意味着除了所有额外元素之外,装饰器还在其可视树中包含input元素.在XAML中,这看起来像:
<custom:Decorator Context="{Binding ValueHelper}" >
<TextBox Text="{Binding ValueHelper.Text}"/>
</custom:Decorator>
Run Code Online (Sandbox Code Playgroud)
这使我们可以轻松地装饰我们想要的任何输入元素,无论是文本框,日期选择器,组合框还是任何自定义元素.
现在回到问题:假设我们有一个包含100个装饰文本框的视图,我们导航到该视图.怎么了?至少我的四核笔记本电脑冻结了很长时间,因为它必须创建数百个文本块,矩形,图像等,以便为每个装饰元素提供视觉反馈,尽管还没有可见的装饰.真正需要的只有100个TextBlocks,因为这是屏幕上可见的内容.只有在元素接收鼠标悬停事件或焦点时才需要其他元素.此外,一次只编辑一个元素,因此只有一个输入元素(在本例中为文本框)足以满足整个应用程序的需要.
那么,如果不为视图中的每个元素创建所有装饰元素(或实际的输入元素),那么实现相同装饰的最佳方法是什么?
用于阐明用例的装饰TextBox的示例:
当文本框没有焦点或鼠标光标当前不在其上时,文本框看起来像只读TextBlock(状态1).此外,示出了三个点("......"),因为元素当前不具有任何值.
当鼠标光标移动到元素顶部时,TextBlock周围会出现一个带绿色的虚线矩形,表示该元素可以被修改(状态2).如果TextBox恰好是只读的,颜色将为红色.
接收到焦点元素后,变成实际的TextBox,可用于修改实际值(状态3).
在文本框失去焦点后,该值将存储到数据库中,并且为了显示当前正在保存该值,将在元素的左侧显示忙指示符(状态4).
最后,该值已被保存,元素返回到显示新值的空闲状态(状态5).(实际上这些元素甚至还有更多与验证和其他特定要求相关的状态,但你肯定认为元素真的是高度装饰的.)

题
基本上我想做以下事情,但似乎我不能:
UserControl myControl = new UserControl();
DataTemplate template = new DataTemplate(myControl);
Run Code Online (Sandbox Code Playgroud)
问题:是否可以从 UserControl 实例构造 DataTemplate?如果没有,还有其他可能的解决方案吗?
真正的问题
我正在做一个项目,其中大部分 UI 视图都是简单的静态 Word 类文档(例如,一些文本字段和一些图像,没什么特别的)。因为在这个项目上工作的大多数人都不是编码员,所以我们为 UI 生成设计了非常简单的内部标记语言。简单视图的标记示例如下:
First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]
Run Code Online (Sandbox Code Playgroud)
现在这些模板在运行时加载,用户控件是基于它们创建的。在这种情况下,将创建一个用户控件,它只包含几个堆栈面板和文本块,因此生成的控件看起来有点像文本文档。XAML 等效项类似于:
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="First name: "/>
<TextBlock Text={Binding Person.FirstName}
</StackPanel>
<StackPanel>
...
</StackPanel>
...
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
然后,我开始实现对列表的支持,但想不出如何做到这一点。理论上它很简单,我想出了以下语法(+ XAML 等效):
[List Customers]
First name: [Person.FirstName]
Last name: [Person.LastName]
Address: [Person.Address.Street], [Person.Address.City]
[EndList]
->
<StackPanel>
<ItemsControl ItemsSource="{Binding Customers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
[Insert code from previous XAML example here] …Run Code Online (Sandbox Code Playgroud)