XAML 条件绑定问题

w8biq8rn  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(126)

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

  • 人员0级,绑定显示视图模型.人员.0级.姓名
  • 人员一级,绑定显示视图模型.人员.一级.名称
  • 人员二级,绑定显示视图模型.人员.二级.姓名

尽管如此,我遇到的问题是没有一个对象像我希望的那样显示。文本框仍然是空的,没有显示任何值。我做错了什么?

<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>
zsbz8rwp

zsbz8rwp1#

这应该行得通。
注:

  • 这段代码使用string而不是Person类中的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>
    • 主页. xaml. cs**
using Microsoft.UI.Xaml.Controls;

namespace ConditionalBindingTest;

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

    public MainPageViewModel ViewModel { get; } = new();
}
    • 主页面视图模型. 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();
}
ckx4rj1h

ckx4rj1h2#

我做错了什么?
1.在不支持x:Bind的地方使用它
1.在视图的XAML标记中实现逻辑
x:Bind直接指向视图模型的另一个只读属性,该属性的定义如下:

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更有表现力、更简洁的语言,虽然它可能 * 有可能 * 只在标记中创建一个相当复杂的视图,但这并不意味着这样做总是一个好主意。在这种情况下,您应该将逻辑移到视图模型或Person类本身。

相关问题