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