简体   繁体   English

条件绑定问题

[英]Conditional Binding Issue

I am currently trying to bind a textbox conditionally based on 3 different objects depending on a Level enum value.我目前正在尝试根据 Level 枚举值根据 3 个不同的对象有条件地绑定文本框。 In the code sample below, what I hoping to achieve is to display values depending on the following condition:在下面的代码示例中,我希望实现的是根据以下条件显示值:

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

With all that, the problem i have is that not of the objects are displaying as i am hoping.尽管如此,我遇到的问题是没有像我希望的那样显示对象。 The textbox remains empty, with no values on display.文本框保持为空,不显示任何值。 What am i doing wrong?我究竟做错了什么?

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

This should work.这应该工作。

Notes:笔记:

  • This code uses a string instead of Level in the Person class because enum binding seems not to work (I'm not sure) with ChangePropertyAction .此代码在Person class 中使用string而不是Level ,因为enum绑定似乎不适用于(我不确定) ChangePropertyAction
  • The MainPage is named as "ThisPage" so we can bind the ViewModel inside the ChangePropertyAction . MainPage被命名为“ThisPage”,因此我们可以在ChangePropertyAction中绑定 ViewModel。

MainPage.xaml主页.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 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 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();
}

What am i doing wrong?我究竟做错了什么?

  1. You use x:Bind where it's not supported在不支持的地方使用x:Bind
  2. You implement logic in the XAML markup of the view您在视图的 XAML 标记中实现逻辑

x:Bind directly to another read-only property of the view model that is defined something like this: 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# is a much more expressive, more concise language than XAML, and while it may be possible to create an entire fairly complex view in markup only, it doesn't mean that it's always a good idea doing so. C# 是一种比 XAML 更具表现力、更简洁的语言,虽然可以仅在标记中创建整个相当复杂的视图,但这并不意味着这样做总是一个好主意。 In this case, you should move the logic to the view model or the Person class itself.在这种情况下,您应该将逻辑移至视图 model 或Person class 本身。

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

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