C# 如何在UWP中动态更改itemtemplate?
在WPF中,您可以通过绑定使用样式和模板动态修改控件。我看到了如何在控件中直接在UWP中执行此操作,但我希望应用一个模板,该模板将根据绑定自行更改 例如按钮。在这个项目中,我有一个开关灯的按钮。该项目已在WPF中创建并运行,但需要转换为UWP。在WPF版本中,我们有一个按钮的LightStyle,根据它是什么类型的灯光,我们更改模板以查看和执行该灯光。例如:我们可以改变一些灯光的颜色,一些灯光的亮度,一些灯光只是打开和关闭;但我们对它们都使用相同的灯光样式。非常通用、动态且非常有用 在UWP中你是如何做到这一点的?我搜索了一分钟,想在继续挖掘的同时停下来检查一下。请记住,这个项目是纯MVVM,没有使用代码隐藏。我不介意解释背后的代码,只要这不是唯一的方法C# 如何在UWP中动态更改itemtemplate?,c#,xaml,uwp,uwp-xaml,C#,Xaml,Uwp,Uwp Xaml,在WPF中,您可以通过绑定使用样式和模板动态修改控件。我看到了如何在控件中直接在UWP中执行此操作,但我希望应用一个模板,该模板将根据绑定自行更改 例如按钮。在这个项目中,我有一个开关灯的按钮。该项目已在WPF中创建并运行,但需要转换为UWP。在WPF版本中,我们有一个按钮的LightStyle,根据它是什么类型的灯光,我们更改模板以查看和执行该灯光。例如:我们可以改变一些灯光的颜色,一些灯光的亮度,一些灯光只是打开和关闭;但我们对它们都使用相同的灯光样式。非常通用、动态且非常有用 在UWP中你
提前感谢:以下是我在特定情况下使用的答案。基本上,您必须使用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中有一个字符串。我希望将模板应用于控件(例如按钮),并根据字符串值应用适当的模板。如果可以的话,你介意给我举个简单的例子吗? 如果它起作用,我可以标记为已回答,并且不管怎样我都会投票。