从 DataTemplateSelector 显式刷新 DataTemplate?

发布于 2024-08-18 09:19:14 字数 124 浏览 8 评论 0原文

我将 ContentControl.DataTemplateSelector 设置为我想要的。
我希望根据命令或其他方式,调用 ContentControl 通过 xaml 或代码从选择器中重新选择模板。

感谢

I set up a ContentControl.DataTemplateSelector to my desired one.
I want that according to a command or whatever, call the ContentControl to reselect the template from the selector by either xaml or code.

Thank

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

通知家属抬走 2024-08-25 09:19:14

我知道,聚会迟到了。 =)

当面对这个问题时,我发现最简单的方法是显式设置一个新的 TemplateSelector,例如

MyContentControl.ContentTemplateSelector =
     new MyDataTemplateSelector();

Late to the party, I know. =)

When faced with this problem, I found it easiest to explicitly set a new TemplateSelector like

MyContentControl.ContentTemplateSelector =
     new MyDataTemplateSelector();
软甜啾 2024-08-25 09:19:14

我想我参加聚会的时间甚至更晚,但是对于可能对某人有所帮助的不同想法...

您也可以尝试在 ContentControl上使用 ValueConverter ContentTemplate 属性而不是 DataTemplateSelector

只需在 DataContext 中有一个属性即可绑定,例如 ScreenNumber。然后在 ValueConverter 中返回与 ScreenNumber 关联的 DataTemplate

ValueConverter 示例:

public class ValueDataTemplateConverter : IValueConverter
{
    public DataTemplate TemplateA { get; set; }
    public DataTemplate TemplateB { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ValueType valueType)
            switch (valueType)
            {
                case ValueType.TypeA:
                    return TemplateA;
                case ValueType.TypeB:
                    return TemplateB;
             }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

xaml 资源示例:

<converters:ValueDataTemplateConverter x:Key="ValueDataTemplateConverter">
    <converters:ValueDataTemplateConverter.TemplateA>
        <DataTemplate>
            <TextBox Text="{Binding Value}" />
        </DataTemplate>
    </converters:ValueDataTemplateConverter.TemplateA>
    <converters:ValueDataTemplateConverter.TemplateB>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Value}" />
        </DataTemplate>
    </converters:ValueDataTemplateConverter.TemplateB>
</converters:ValueDataTemplateConverter>

I guess I am even later to the party, but for a different idea that may help someone...

You could also try using a ValueConverter on the ContentControls ContentTemplate property instead of a DataTemplateSelector.

Just have a property in your DataContext to bind, like ScreenNumber for example. Then in the ValueConverter return the DataTemplate that is associated with the ScreenNumber.

Example ValueConverter:

public class ValueDataTemplateConverter : IValueConverter
{
    public DataTemplate TemplateA { get; set; }
    public DataTemplate TemplateB { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ValueType valueType)
            switch (valueType)
            {
                case ValueType.TypeA:
                    return TemplateA;
                case ValueType.TypeB:
                    return TemplateB;
             }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Example xaml resource:

<converters:ValueDataTemplateConverter x:Key="ValueDataTemplateConverter">
    <converters:ValueDataTemplateConverter.TemplateA>
        <DataTemplate>
            <TextBox Text="{Binding Value}" />
        </DataTemplate>
    </converters:ValueDataTemplateConverter.TemplateA>
    <converters:ValueDataTemplateConverter.TemplateB>
        <DataTemplate>
            <CheckBox IsChecked="{Binding Value}" />
        </DataTemplate>
    </converters:ValueDataTemplateConverter.TemplateB>
</converters:ValueDataTemplateConverter>
你的背包 2024-08-25 09:19:14

我不知道有任何(非笨拙的)方法可以做到这一点:当 WPF 需要选择模板时,将调用 DataTemplateSelector,就 WPF 而言,这是一个一次性决定。 (你可以通过让 WPF 认为内容已经改变来拼凑它,例如通过将内容设置为 null 然后再返回 - 我认为这会起作用,但还没有测试它 - 但这是相当丑陋的!)如果有一个很好的方法,我也有兴趣知道!

但是,还有另一种方法可以更改内容的显示方式,并根据数据更改进行更新,那就是通过触发器。您可以使用 DataTemplate.Triggers 集合中的 DataTriggers 来根据内容数据显示和隐藏元素。要更改整个显示,您可以在网格中设置两个渲染,并使用触发器来控制哪一个可见。您甚至可以将数据模板设为 ContentControl,并使用触发器来更改 ContentTemplate。当然,这取决于将模板更改为可绑定属性的标准,但情况可能并不总是如此。

这里有一些对选择器与触发器的简要讨论,尽管上下文略有不同。

I'm not aware of any (non-kludgy) way to do this: the DataTemplateSelector is called when WPF needs to select the template, and that's a one-off decision as far as WPF is concerned. (You can kludge it by making WPF think the content has changed, e.g. by setting the content to null and then back again -- I think that would work but haven't tested it -- but this is pretty ugly!) If there is a nice way to do this I too would be interested to know!

However, there is an alternative way to change how content is displayed that does update in response to data changes, and that is through triggers. You can use DataTriggers in your DataTemplate.Triggers collection to show and hide elements depending on the content data. To change the entire display, you could e.g. set up two renderings in a Grid, and use triggers to control which one is visible. You could even make your data template a ContentControl, and use a trigger to change the ContentTemplate. Of course this depends on the criteria for changing the template being bindable properties, which may not always be the case.

Here's some brief discussion of selectors vs. triggers, albeit in a slightly different context.

樱花细雨 2024-08-25 09:19:14

与 Jens 的回答类似,您可以使用 DataTemplateSelector 的现有实例,而不是创建新实例。

var currentSelector = MyContentControl.ContentTemplateSelector;     
MyContentControl.ContentTemplateSelector = null;
MyContentControl.ContentTemplateSelector = currentSelector;

Similar to Jens answer, instead of creating a new instance , you can use the existing instance of the DataTemplateSelector.

var currentSelector = MyContentControl.ContentTemplateSelector;     
MyContentControl.ContentTemplateSelector = null;
MyContentControl.ContentTemplateSelector = currentSelector;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文