gpt4 book ai didi

c# - 将模板选择器中的 DataTemplate 设置为动态资源

转载 作者:行者123 更新时间:2023-11-30 17:04:31 25 4
gpt4 key购买 nike

我有一个控件,我需要根据各种条件在其中设置数据模板,所以我决定使用 DataTemplateSelector,它从分配给控件的资源中选择模板。

这是有效的,但这里有一个问题:我正在从文件中重新加载这些资源(当文件系统发生变化时),我需要使用新模板更新已经呈现的控件。如果我简单地使用 DynamicResource 而不是选择器,这将起作用。

选择器看起来像这样:

public override DataTemplate SelectTemplate(object item, DependencyObject container) {
//complex rules that select the template are here
//this unfortunately sets the template statically - if it changes, it won't get updated
return template;
}

因此,如果资源发生变化,选择器永远不会像我使用 DynamicResource 时那样重新求值。

我有一个解决这个问题的想法:在 ViewModel 中选择模板,这样当资源发生变化时,我可以更新我的 DataTemplate 属性。

我对 ViewModel 的尝试(简化示例,它正确地实现了 INotifyPropertyChange):

class MyViewModel {
public DataTemplate DataTemplate {get;set;}

public MyModel Model {
get {return _model;}
set {
if(_model != value) {
_model = value;
//Select new template here
//DUH: how do I access the resources as I would in DataTemplateSelector, when I don't have access to the container parameter?
}
}
}
}

我很确定我做错了,但如何正确地做呢?出于各种原因,我不想从一些硬编码的静态位置访问资源。我真的需要在分配给它的容器中找到它们。

我知道这个问题令人困惑,所以尽管提问,我会尽力澄清。

最佳答案

因此,经过长时间尝试使用各种骇人听闻的方法来解决这个问题后,事实证明这是一个非常容易解决的问题。

我们在 View 模型中设置我们的数据模板(实际上只是数据模板的键),然后在简单的附加属性中应用该模板。

xaml:

<ContentControl Content="{Binding Content}" local:ContentTemplate.ContentTemplateKey="{Binding TemplateKey}">
<!-- Some other stuff -->
</ContentControl>

附加属性:

public static class ContentTemplate
{

public static object GetContentTemplateKey(DependencyObject obj)
{
return (object)obj.GetValue(ContentTemplateKeyProperty);
}

public static void SetContentTemplateKey(DependencyObject obj, object value)
{
obj.SetValue(ContentTemplateKeyProperty, value);
}

public static readonly DependencyProperty ContentTemplateKeyProperty = DependencyProperty.RegisterAttached("ContentTemplateKey", typeof(object), typeof(ContentTemplate), new UIPropertyMetadata(null, OnContentTemplateKeyChanged));

private static void OnContentTemplateKeyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var key = e.NewValue;

var element = d as FrameworkElement;
if (element == null)
return;

element.SetResourceReference(ContentControl.ContentTemplateProperty, key);
}
}

如果资源使用 x:Key="ResourceName" 则绑定(bind)对象:

new
{
Content = something,
TemplateKey = "ResourceName",
}

如果资源使用 TargetType="{x:Type Person}" 则绑定(bind)对象:

new
{
Content = something,
TemplateKey = new DataTemplateKey(typeof(Person)),
}

当然,绑定(bind)对象应该实现 INotifyPropertyChange,以便模板即时更新。

关于c# - 将模板选择器中的 DataTemplate 设置为动态资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17431883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com