Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在UWP中动态更改itemtemplate?_C#_Xaml_Uwp_Uwp Xaml - Fatal编程技术网

C# 如何在UWP中动态更改itemtemplate?

C# 如何在UWP中动态更改itemtemplate?,c#,xaml,uwp,uwp-xaml,C#,Xaml,Uwp,Uwp Xaml,在WPF中,您可以通过绑定使用样式和模板动态修改控件。我看到了如何在控件中直接在UWP中执行此操作,但我希望应用一个模板,该模板将根据绑定自行更改 例如按钮。在这个项目中,我有一个开关灯的按钮。该项目已在WPF中创建并运行,但需要转换为UWP。在WPF版本中,我们有一个按钮的LightStyle,根据它是什么类型的灯光,我们更改模板以查看和执行该灯光。例如:我们可以改变一些灯光的颜色,一些灯光的亮度,一些灯光只是打开和关闭;但我们对它们都使用相同的灯光样式。非常通用、动态且非常有用 在UWP中你

在WPF中,您可以通过绑定使用样式和模板动态修改控件。我看到了如何在控件中直接在UWP中执行此操作,但我希望应用一个模板,该模板将根据绑定自行更改

例如按钮。在这个项目中,我有一个开关灯的按钮。该项目已在WPF中创建并运行,但需要转换为UWP。在WPF版本中,我们有一个按钮的LightStyle,根据它是什么类型的灯光,我们更改模板以查看和执行该灯光。例如:我们可以改变一些灯光的颜色,一些灯光的亮度,一些灯光只是打开和关闭;但我们对它们都使用相同的灯光样式。非常通用、动态且非常有用

在UWP中你是如何做到这一点的?我搜索了一分钟,想在继续挖掘的同时停下来检查一下。请记住,这个项目是纯MVVM,没有使用代码隐藏。我不介意解释背后的代码,只要这不是唯一的方法


提前感谢:

以下是我在特定情况下使用的答案。基本上,您必须使用VisualStateTrigger并通过代码手动创建触发器。有各种各样的触发器可以使用,还有许多内置的,但是对于这种情况,我必须,或者至少我认为我必须,手动编写一个

这是触发代码

public class StringComparisonTrigger : StateTriggerBase
{
    private const string NotEqual = "NotEqual";
    private const string Equal = "Equal";

    public string DataValue
    {
        get { return (string)GetValue(DataValueProperty); }
        set { SetValue(DataValueProperty, value); }
    }

    public static readonly DependencyProperty DataValueProperty =
        DependencyProperty.Register(nameof(DataValue), typeof(string), typeof(StringComparisonTrigger), new PropertyMetadata(Equal, (s, e) =>
        {
            var stringComparisonTrigger = s as StringComparisonTrigger;
            TriggerStateCheck(stringComparisonTrigger, stringComparisonTrigger.TriggerValue, (string)e.NewValue);
        }));


    public string TriggerValue
    {
        get { return (string)GetValue(TriggerValueProperty); }
        set { SetValue(TriggerValueProperty, value); }
    }

    public static readonly DependencyProperty TriggerValueProperty =
        DependencyProperty.Register(nameof(TriggerValue), typeof(string), typeof(StringComparisonTrigger), new PropertyMetadata(NotEqual, (s, e) =>
        {
            var stringComparisonTrigger = s as StringComparisonTrigger;
            TriggerStateCheck(stringComparisonTrigger, stringComparisonTrigger.DataValue, (string)e.NewValue);
        }));


    private static void TriggerStateCheck(StringComparisonTrigger elementTypeTrigger, string dataValue, string triggerValue)
        => elementTypeTrigger.SetActive(dataValue == triggerValue);
}
这是因为从StateTriggerBase继承可以在VisualStateTriggers组中使用,我将在下面发布。我不知道的是,您编写的任何依赖属性都可以在XAML中使用,并且触发器中没有接口或任何东西使其工作。触发触发器的唯一一行代码是“SetActivebool value”,您必须在希望状态更改时调用它。通过在XAML中设置依赖项属性和绑定,可以在属性更改时激活SetActive,从而修改可视状态

下面是数据模板

<DataTemplate x:Key="LightsButtonTemplate">

    <UserControl>
        <StackPanel Name="panel">

            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState>
                        <VisualState.StateTriggers>
                            <DataTriggers:StringComparisonTrigger DataValue="{Binding Type}"
                                                                  TriggerValue="READ" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <Setter Target="panel.(UIElement.Background)"
                                    Value="Red" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

            <TextBlock Text="{Binding Type}" />
            <TextBlock Text="{Binding LightStateViewModel.On}" />

        </StackPanel>
    </UserControl>

</DataTemplate>
最后使用,您可以在任何地方使用DataTemplate,但我在绑定到LightViewModels列表的ItemsControl中使用它

    <ScrollViewer Grid.Row="1">
        <ItemsControl ItemsSource="{Binding LightViewModels}"
                      ItemTemplate="{StaticResource LightsButtonTemplate}" />
    </ScrollViewer>
显然,这不是我想要的灯光按钮的模板设计,但这是我所做的一切,以了解并实现动态模板。希望这能帮助来自WPF的其他人

从StateTriggerBase派生的自定义触发器类可以执行并绑定您希望它执行的任何操作,并且只要在您希望更新该触发器时调用SetActivetrue或SetActivefalse即可。如果为真,则使用该触发器的VisualState将处于活动状态。

-XAML:

以及背后的代码:

公共密封部分类主页面:第页,INotifyPropertyChanged { 公共事件属性更改事件处理程序属性更改; private void RaisePropertystring name=>PropertyChanged?.Invokethis,new PropertyChangedEventArgsname; private bool isSwitched=假; 公共图书馆是有开关的 { 获取{return isSwitched;} 设置{isSwitched=value;RaisePropertynameofIsSwitched;} } 公共主页{this.InitializeComponent;} 私有void AddClickobject发送者,RoutedEventArgs e { ListOfItems.Items.addnewitemclass{Type=isSwitched?ItemType.Greed:ItemType.Red,Text=newitem}; } } 公共枚举项类型{Red,Greed}; 公共类ItemClass { 公共ItemType类型{get;set;} 公共字符串文本{get;set;} } 公共类MySelector:DataTemplateSelector { 受保护的覆盖数据模板SelectTemplateCoreobject项,DependencyObject容器 { 将项切换为ItemClass.Type { 案例项目类型。贪婪: 返回绿色模板; 案例项目类型。红色: 违约: 返回RedTemplate; } } 公共数据模板GreenTemplate{get;set;} 公共数据模板RedTemplate{get;set;} }
一般来说,您可以为选择器选择各种开关,这取决于您的需要。在上面的示例中,我根据项的属性切换模板,即如何切换项的类型

你想过使用哪一个会根据你的需要来关联适当的ItMeT模板吗?这有点尴尬,因为我认为自己对XAML很好,但实际上我从来没有使用过DATATEMAPPLS选择器。在回答之前,我做了一些研究来了解它,我不确定我是否完全理解它。我的ViewModel中有一个字符串。我希望将模板应用于控件(例如按钮),并根据字符串值应用适当的模板。如果可以的话,你介意给我举个简单的例子吗? 如果它起作用,我可以标记为已回答,并且不管怎样我都会投票。