[英]How can I bind WPF TextBlock text to different properties?
Based on MVVM Pattern, I have these two properties in my MODEL : 基于MVVM模式,我在MODEL中具有以下两个属性:
public string DestinationCode
AND 和
public enum OperatingMode
{
Unknown,
[Description("Zzz")]
Asleep,
Standby,
[Description("WKU")]
WakeUp
}
Senario : I want the TextBlock Text shows : Senario:我想要TextBlock Text显示:
-DestinationCode -目的地代码
-"Zzz" if the OperatingMode is 'asleep' -如果OperatingMode为“睡眠”,则为“ Zzz”
-"WKU" if the OperatingMode is 'WakeUp' -如果OperatingMode为“ WakeUp”,则为“ WKU”
For your property DestinationCode
, the binding need INotifyPropertychange
to alert his change. 对于您的属性
DestinationCode
,绑定需要INotifyPropertychange
来提醒他的更改。 For ex, this is your class: 例如,这是您的课程:
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));
}
}
To binding your enum My_Enum
, you must first create a converter to get the description of enum. 要绑定枚举
My_Enum
,必须首先创建一个转换器以获取枚举的描述。 Something likes : 喜欢的东西:
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;
}
}
Next, your TextBox
should use this converter 接下来,您的
TextBox
应该使用此转换器
<TextBox Text="{Binding My_Enum, Converter={StaticResource EnumDescriptionConverter}}"/>
Assuming that the text should show the DestinationCode unless the OperatingMode is set to a value that has a description: 假定文本应显示DestinationCode,除非OperatingMode设置为具有描述的值:
A solution would be to use a multi binding and a multi value converter. 一种解决方案是使用多绑定和多值转换器。
Example: 例:
<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>
The multivalue converter could look like this: 多值转换器看起来像这样:
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();
}
The ViewModel would look like this: 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.