繁体   English   中英

如何将WPF TextBlock文本绑定到其他属性?

[英]How can I bind WPF TextBlock text to different properties?

基于MVVM模式,我在MODEL中具有以下两个属性:

public string DestinationCode

public enum OperatingMode
{
    Unknown,
    [Description("Zzz")]
    Asleep,
    Standby,
    [Description("WKU")]
    WakeUp
}

Senario:我想要TextBlock Text显示:

-目的地代码

-如果OperatingMode为“睡眠”,则为“ Zzz”

-如果OperatingMode为“ WakeUp”,则为“ WKU”

对于您的属性DestinationCode ,绑定需要INotifyPropertychange来提醒他的更改。 例如,这是您的课程:

public class Your_Class: INotifyPropertyChanged
{
    private string _destinationCode;
    public string DestinationCode
    {
        get
        {
            return _destinationCode;
        }
        set
        {
            _destinationCode = value;
            RaisePropertyChanged("DestinationCode");
        }
    }

    private OperatingMode _my_Enum;
    public OperatingMode My_Enum
    {
        get
        {
            return _my_Enum;
        }
        set
        {
            _my_Enum = value;
            RaisePropertyChanged("My_Enum");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

要绑定枚举My_Enum ,必须首先创建一个转换器以获取枚举的描述。 喜欢的东西:

public class EnumDescriptionConverter : IValueConverter
{
    private string GetEnumDescription(Enum enumObj)
    {
        FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

        object[] attribArray = fieldInfo.GetCustomAttributes(false);

        if (attribArray.Length == 0)
        {
            return enumObj.ToString();
        }
        else
        {
            DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
            return attrib.Description;
        }
    }

    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Enum myEnum = (Enum)value;
        string description = GetEnumDescription(myEnum);
        return description;
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return string.Empty;
    }
}

接下来,您的TextBox应该使用此转换器

<TextBox Text="{Binding My_Enum, Converter={StaticResource EnumDescriptionConverter}}"/>

假定文本应显示DestinationCode,除非OperatingMode设置为具有描述的值:

一种解决方案是使用多绑定和多值转换器。

例:

<Window x:Class="WpfApp3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfApp3"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Width="200"
        Height="150"
        mc:Ignorable="d">
    <Window.Resources>
        <local:DestinationAndOperationModeToDescriptionConverter x:Key="DestinationAndOperationModeToDescription" />
    </Window.Resources>
    <Grid>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource DestinationAndOperationModeToDescription}">
                    <Binding Path="DestinationCode" />
                    <Binding Path="OperatingMode" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </Grid>
</Window>

多值转换器看起来像这样:

public class DestinationAndOperationModeToDescriptionConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values == null || values.Length < 2)
        {
            return DependencyProperty.UnsetValue;
        }

        string destinationCode;
        OperatingMode operatingMode;
        if (values[0] is string && values[1] is OperatingMode)
        {
            destinationCode = values[0] as string;
            operatingMode = (OperatingMode)values[1];
        }
        else if (values[1] is string && values[0] is OperatingMode)
        {
            destinationCode = values[1] as string;
            operatingMode = (OperatingMode)values[0];
        }
        else
        {
            return DependencyProperty.UnsetValue;
        }

        var descriptionAttribute =
            typeof(OperatingMode)
                .GetField(operatingMode.ToString())
                .GetCustomAttributes(typeof(DescriptionAttribute), false)
                .OfType<DescriptionAttribute>().FirstOrDefault();

        if (string.IsNullOrEmpty(descriptionAttribute?.Description))
        {
            return destinationCode;
        }

        return descriptionAttribute.Description;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotImplementedException();
}

ViewModel看起来像这样:

public class MyViewModel : INotifyPropertyChanged
{
    private string destinationCode;
    private OperatingMode operatingMode;

    public event PropertyChangedEventHandler PropertyChanged;

    public string DestinationCode
    {
        get
        {
            return destinationCode;
        }

        set
        {
            if (this.destinationCode == value)
            {
                return;
            }
            destinationCode = value;
            this.OnPropertyChanged();
        }
    }

    public OperatingMode OperatingMode
    {
        get
        {
            return operatingMode;
        }

        set
        {
            if (this.operatingMode == value)
            {
                return;
            }
            operatingMode = value;
            this.OnPropertyChanged();
        }
    }

    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

暂无
暂无

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

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