繁体   English   中英

条件绑定问题

[英]Conditional Binding Issue

我目前正在尝试根据 Level 枚举值根据 3 个不同的对象有条件地绑定文本框。 在下面的代码示例中,我希望实现的是根据以下条件显示值:

  • Person Level0 ,绑定/显示 ViewModel.Person。 Level0.名称
  • Person Level1 ,绑定/显示 ViewModel.Person。 Level1 .名称
  • Person Level2 ,绑定/显示 ViewModel.Person。 Level2 .名称

尽管如此,我遇到的问题是没有像我希望的那样显示对象。 文本框保持为空,不显示任何值。 我究竟做错了什么?

<TextBox Margin="0,0,0,5">
    <interactivity:Interaction.Behaviors>
        <core:DataTriggerBehavior Binding="{x:Bind ViewModel.Person.Level, FallbackValue='', Mode=OneWay}" ComparisonCondition="Equal" Value="Level0">
            <core:ChangePropertyAction PropertyName="Text" Value="{x:Bind ViewModel.Person.Level0.Name, FallbackValue=''}" />
        </core:DataTriggerBehavior>
        <core:DataTriggerBehavior Binding="{x:Bind ViewModel.Person.Level, FallbackValue='', Mode=OneWay}" ComparisonCondition="Equal" Value="Level1">
            <core:ChangePropertyAction PropertyName="Text" Value="{x:Bind ViewModel.Person.Level1.Name, FallbackValue='', Mode=OneWay}" />
        </core:DataTriggerBehavior>
        <core:DataTriggerBehavior Binding="{x:Bind ViewModel.Person.Level, FallbackValue='', Mode=OneWay}" ComparisonCondition="Equal" Value="Level2">
            <core:ChangePropertyAction PropertyName="Text" Value="{x:Bind ViewModel.Person.Level2.Name, FallbackValue='', Mode=OneWay}" />
        </core:DataTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</TextBox>

这应该工作。

笔记:

  • 此代码在Person class 中使用string而不是Level ,因为enum绑定似乎不适用于(我不确定) ChangePropertyAction
  • MainPage被命名为“ThisPage”,因此我们可以在ChangePropertyAction中绑定 ViewModel。

主页.xaml

<Page
    x:Class="ConditionalBindingTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:local="using:ConditionalBindingTest"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Name="ThisPage"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">
    <Grid>
        <TextBox>
            <interactivity:Interaction.Behaviors>
                <core:DataTriggerBehavior
                    Binding="{x:Bind ViewModel.Person.Level, Mode=OneWay}"
                    ComparisonCondition="Equal"
                    Value="Level0">
                    <core:ChangePropertyAction
                        PropertyName="Text"
                        Value="{Binding ElementName=ThisPage, Path=ViewModel.Person.Level0.Name, Mode=OneWay}" />
                </core:DataTriggerBehavior>
                <core:DataTriggerBehavior
                    Binding="{x:Bind ViewModel.Person.Level, Mode=OneWay}"
                    ComparisonCondition="Equal"
                    Value="Level1">
                    <core:ChangePropertyAction
                        PropertyName="Text"
                        Value="{Binding ElementName=ThisPage, Path=ViewModel.Person.Level1.Name, Mode=OneWay}" />
                </core:DataTriggerBehavior>
            </interactivity:Interaction.Behaviors>
        </TextBox>
    </Grid>
</Page>

MainPage.xaml.cs

using Microsoft.UI.Xaml.Controls;

namespace ConditionalBindingTest;

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    public MainPageViewModel ViewModel { get; } = new();
}

MainPageViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;

namespace ConditionalBindingTest;

public enum Level
{
    Level0,
    Level1,
}

public class LevelName
{
    public LevelName(Level level)
    {
        Name = $"{level} Name";
    }

    public string Name { get; }
}

public class Person
{
    public string Level { get; } = ConditionalBindingTest.Level.Level0.ToString();

    public LevelName Level0 { get; } = new(ConditionalBindingTest.Level.Level0);

    public LevelName Level1 { get; } = new(ConditionalBindingTest.Level.Level1);
}

public partial class MainPageViewModel : ObservableObject
{
    [ObservableProperty]
    private Person person = new();
}

我究竟做错了什么?

  1. 在不支持的地方使用x:Bind
  2. 您在视图的 XAML 标记中实现逻辑

x:Bind到视图 model 的另一个只读属性,其定义如下:

public string DisplayValue
{
    get
    {
        switch (Person.Level)
        {
            case "Level0":
                return Person.Level0.Name;
            case "Level1":
                return Person.Level1.Name;
            case "Level2":
                return Person.Level2.Name;
        }

        return string.Empty;
    }
}

C# 是一种比 XAML 更具表现力、更简洁的语言,虽然可以仅在标记中创建整个相当复杂的视图,但这并不意味着这样做总是一个好主意。 在这种情况下,您应该将逻辑移至视图 model 或Person class 本身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM