XAML 如何在状态更改时将样式应用于MAUI中的所有内部元素

2sbarzqh  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(147)

这基本上是一个简单的UI,如果绑定的ShowContent属性是True,它将有条件地呈现一个带有文本Triggered - plain的标签。(这里的示例过于简化,但它可以工作,我可以看到标签切换)。

<Grid>
   <Button Click="ChangeState"/>
   <ContentView>
      <ContentView.Style>
            <Style TargetType="ContentView">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ShowContent}" Value="True" TargetType="ContentView">
                        <Setter Property="ControlTemplate">
                            <Setter.Value>
                                <ControlTemplate>
                                    <Label>Triggered - Plain</Label>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentView.Style>
   </ContentView>
</Grid>

还有一个按钮可以切换Grid的状态:

public void ChangeState(object sender, EventArgs e){
    this.state = !this.state; // toggle
    if(this.state){
      VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Selected);
    } else {
      VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Normal);
    }
}

问题

我不确定如何基于选定状态将不同的样式应用于标签。
如果您使用VisualStateManager,您需要在Label上有一个名称。我想在所有内部标签上以覆盖的方式应用选定的样式。
此外,如果我们以名称作为标签的目标,当Label不在UI上时(由于状态ShowContentFalse),GoToState会失败,并出现空异常,因为它找不到标签。
最好的解决方案似乎是使用CSS,但它不支持定义的颜色和动态资源(AFAIK)。
你知道该怎么做吗?

Update:一种可能的解决方案是将状态更改应用于所有内部元素:

private IList<T> FindAllChildren<T>()
    where T : IVisualTreeElement
{
    return this.GetVisualTreeDescendants()
        .Where(e => e is T)
        .Cast<T>()
        .ToList();
}

private void ApplyState(string state)
{
    VisualStateManager.GoToState(this, state);
    FindAllChildren<VisualElement>().ForEach(e => VisualStateManager.GoToState(e, state));
}

public void ChangeState(object sender, EventArgs e){
    this.state = !this.state; // toggle
    if(this.state){
      ApplyState(VisualStateManager.CommonStates.Selected);
    } else {
      ApplyState(VisualStateManager.CommonStates.Normal);
    }
}

您仍然需要为标签创建VisualStateGroup样式并为标签指定特定的样式/类:
第一个

osh3o9ms

osh3o9ms1#

我建议你解决这个问题。太多的bug,以及容器在不同平台上的不同行为。
修复视觉状态是一回事。然后你需要修复“IsEnabled”的子问题。之后如果你改变可见性,你会注意到它在IOS上做一件事,在android上做另一件事。(你会开始不时失去这种视觉状态)。在某个时候,你会开始寻找方法来迫使页面重绘自己。
我的建议是,就目前而言,给予这个想法。直到那些问题得到解决。浪费了太多的时间试图让这个对所有平台都有效。
(Some的问题是6个多月前的,他们不断将其推到积压状态。)
这是我,一个月前问同样的问题:Pass the VisualState of CollectionView Item VisualElement to its child VisualElements

相关问题