【发布时间】:2020-12-04 02:42:13
【问题描述】:
我在 xaml 中有许多非常相似的资源(略有不同:bingings 中的属性名称、标题中的静态文本等),它们非常庞大且复杂:
<Window.Resource>
<A x:Key="a1"> ... </A>
<A x:Key="a2"> ... </A>
...
<B x:Key="b1"> ... />
<B x:Key="b2"> ... />
...
<C x:Key="c1"> ... />
...
</Window.Resource>
而我的目标就是拥有这个:
<A x:Key="a" ... />
<B x:Key="b" ... />
<C x:Key="c" ... />
...
资源成为一种模板。但是我需要在使用它之前以某种方式定义一个 参数 来更改每个此类资源(例如修改绑定中的属性名称)。
我目前的想法是将资源作为文本来操作:
var xaml = @"... Text = ""{Binding %PROPERTY%}"" ...";
xaml = xaml.Replace("%PROPERTY%", realPropertyName);
view.Content = XamlReader.Parse(xaml)
但是在代码隐藏中定义 xaml 字符串听起来不太好,它们应该是 xaml 的一部分,在那里使用它们。
所以我有了这个绝妙的想法:
// get some resource and restore xaml string for it, yay!
var xaml = XamlWriter.Save(FindResource("some resource"));
但不幸的是XamlWriter 非常有限,它没有工作,恢复这种方式 xaml 完全无法使用。
然后我想到了将资源定义为字符串:
<clr:String x:Key="a">...</clr:String>
但是 multiline 字符串和 xaml 中的特殊字符使这种方法看起来很丑陋。不要在家里尝试。
理想情况下,我想像以前一样定义资源(拥有智能和东西),只是想在运行时以某种方式修改它们,因此我的问题。
问题的本地化案例(完全一样)是在DataTemplate 中有参数。我之前问过关于dynamic columns 的问题,这就是为什么我目前定义了这么多类似的资源并试图再次找到解决方案。
我忘了添加资源的具体示例以及某种形式的 MCVE:
<Window.Resources>
<GridViewColumn x:Key="column1">
<GridViewColumn.Header>
<DataTemplate>
<TextBlock Text="Header1" />
</DataTemplate>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value1}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
...
... more similar columns
...
</Window.Resources>
<ListView x:Name="listView" ItemsSource="{Binding Items}">
<ListView.View>
<GridView />
</ListView.View>
</ListView>
添加了一些列
var view = (GridView)listView.View;
foreach(var column in Columns.Where(o => o.Show))
view.Columns.Add((GridViewColumn)FindResouce(column.Key));
Columns 集合定义了哪些列可以显示,哪些是隐藏的,它们的宽度等。
public class Column
{
public string Key { get; set; } // e.g. "column1"
public bool Show { get; set; }
...
}
要拥有 100 列,我必须定义 100 个"columnX" 资源,但它们非常相似。我的挑战是只定义一个,然后以某种方式更改动态部分(在这种情况下,将"Header1" 更改为"Header2" 和"Value1" 更改为"Value2")。
【问题讨论】:
-
这些资源会根据什么改变,即改变该名称的标准是什么?顺便说一句,在运行时更改名称听起来很可疑。我有一种感觉,这可能部分是设计问题,但现在说还为时过早。另一种方法是将这些导出到单独的字典中,并尝试根据...加载它们
-
@XAMlMAX,我已经用示例编辑了帖子。虽然我的两篇文章都是关于动态列的,但我可以将解决方案(如果存在)用于其他事情,以减少 xaml 的冗长。
-
这听起来就像你想在 xaml 中拥有你的模型。
-
我认为我没有完全理解您的意图,因为我没有看到问题所在。为什么不使用简单的
DataTemplateSelector?你提前知道源数据模型的所有属性吗?
标签: c# wpf xaml resources datatemplate