UWP Xaml,在运行时更改 ContentControl 的 DataTemplate,具体取决于其 DataContext 上的属性值



请我有一个ContentControl,它显示ListView上单击的项目的详细信息,单击的项目在运行时设置为内容控件的DataContext,我愿意知道如何在每次更新Datacontext时更改此ContentControlDataTemplate,具体取决于DataTemplateSelectorDataContext的值,但是, 模板仅设置一次,当DataContext更改时,此初始模板不会根据需要更新。所以,我决定继续使用VisualTriggers,但这似乎也不起作用,因为当我使用这种方法时,DataTemplate甚至没有显示。 这是我使用 DataTrigger 时的代码:

<ContentControl x:Name="baseTemplate" DataContext="{Binding Selected}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Uno">
<VisualState.StateTriggers>
<dataTriggers:FocusDataTrigger
dataTriggers:FocusDataTrigger.TriggerValue="Uno"
dataTriggers:FocusDataTrigger.DataValue="{Binding DataContext.Type}"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="baseTemplate.Template" Value="{StaticResource UnoTemplate}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Duo">
<VisualState.StateTriggers>
<dataTriggers:FocusDataTrigger
dataTriggers:FocusDataTrigger.TriggerValue="Duo"
dataTriggers:FocusDataTrigger.DataValue="{Binding  DataContext.Type}"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="baseTemplate.Template" Value="{StaticResource detailTemplateSelector}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</ContentControl>

我希望everytime设置为DataContext的值具有值"Uno""Duo"的属性Type进行DataTemplate更改 请帮忙!,我已经尽我所能尝试了,但我找不到解决方案。

我使用自定义数据触发器

public class FocusDataTrigger : StateTriggerBase
{
#region DataValue
public static readonly DependencyProperty DataValueProperty =
DependencyProperty.RegisterAttached("DataValue", typeof(object),
typeof(FocusDataTrigger), new PropertyMetadata(null, DataValueChanged));
public static object GetDataValue(DependencyObject obj)
{
return obj.GetValue(DataValueProperty);
}
public static void SetDataValue(DependencyObject obj, object value)
{
obj.SetValue(DataValueProperty, value);
}
#endregion
#region TriggerValue
public static readonly DependencyProperty TriggerValueProperty =
DependencyProperty.RegisterAttached("TriggerValue", typeof(object),
typeof(FocusDataTrigger), new PropertyMetadata(false, TriggerValueChanged));

public static object GetTriggerValue(DependencyObject obj)
{
return obj.GetValue(TriggerValueProperty);
}
public static void SetTriggerValue(DependencyObject obj, object value)
{
obj.SetValue(TriggerValueProperty, value);
}
#endregion
private static void TriggerStateCheck(DependencyObject target, object datavalue, object triggerValue)
{
FocusDataTrigger trigger = target as FocusDataTrigger;
if (trigger == null) return;
trigger.SetActive(triggerValue == datavalue);
}
private static void TriggerValueChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
object datavalue = target.GetValue(FocusDataTrigger.DataValueProperty);
TriggerStateCheck(target, datavalue, e.NewValue);
}
private static void DataValueChanged(DependencyObject target,
DependencyPropertyChangedEventArgs e)
{
object triggerValue = target.GetValue(FocusDataTrigger.TriggerValueProperty);
TriggerStateCheck(target, e.NewValue, triggerValue);
}
}

看来你走错了方向。

您的模板将根据更改的属性而更改。

我不太确定你在这里的意思。DataContextChanged 表示您正在切换数据上下文。但似乎在这里你只是想根据属性值改变事情,我说得对吗?

尝试执行以下步骤:

  1. 创建数据模板选择器:

    public class CCDataTemplateSelector: DataTemplateSelector
    {
    public DataTemplate FirstTemplate { get; set; }
    public DataTemplate SecondTemplate { get; set; }
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
    var model = item as DemoModel;
    if (model == null)
    return null;
    if (model.ID >= 2)
    return FirstTemplate;
    else
    return SecondTemplate;
    }
    }
    
  2. 然后在 XAML 中,可以编写如下内容:

    <StackPanel.Resources>
    <DataTemplate x:Key="FirstTemplate">
    xxxxx
    </DataTemplate>
    <DataTemplate x:Key="SecondTemplate">
    xxxxx
    </DataTemplate>
    <local:CCDataTemplateSelector FirstTemplate="{StaticResource FirstTemplate}"
    SecondTemplate="{StaticResource SecondTemplate}"
    x:Key="DataTemplateSelector" />
    <Style TargetType="ContentControl">
    <Setter Property="ContentTemplateSelector" Value="{StaticResource DataTemplateSelector}" />
    </Style>
    </StackPanel.Resources>
    

这样,模板将根据您在模型中设置的值而有所不同。

最新更新