我有一个填充组合框的“发票操作”枚举,但我想根据 ViewModel 中的“CanDisplayDetails”属性禁用枚举成员之一(“View”)。
我不太清楚如何将 IsEnabled 属性绑定(bind)到 ComboBoxItem ItemContainerStyle 中的“CanDisplayDetails”,因为上下文似乎是 Enum 而不是我的 ViewModel。如何更正绑定(bind),以便它可以提供枚举值,但 IsEnabled 绑定(bind)到我的 ViewModel 属性?而且它还需要只影响“View”ComboBoxItem。谢谢!
到目前为止的风格想法:
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="IsEnabled" Value="{Binding CanDisplayDetails}"/>
</Style>
</ComboBox.ItemContainerStyle>
在 XAML UserControl 的资源中:
<ObjectDataProvider x:Key="ActionsEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:TypeExtension TypeName="Constants:InvoiceActionsLong"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
同一用户控件中的组合框:
<ComboBox Grid.Column="1" ItemsSource="{Binding Source={StaticResource ActionsEnum}}" IsEnabled="{Binding SelectedItem, Converter={StaticResource SelectionConverter}}"
SelectedItem="{Binding SelectedAction}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding ActionCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
EnumDescriptionConverter:
public class EnumDescriptionConverter : IValueConverter
{
/// <summary>
/// Get enum description
/// </summary>
/// <param name="enumObj"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// Returns an enum member's description
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
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;
}
}
枚举:
/// <summary>
/// Enum lists all available Actions for Action Combo Box at the Invoice level for DETAIL types ie. active, plan
/// </summary>
public enum InvoiceActionsLong
{
[Description("Contacts")]
Contacts,
[Description("Delivery")]
Delivery,
[Description("Documents")]
Documents,
[Description("Note")]
Note,
[Description("Payments")]
Payments,
[Description("Print")]
Print,
[Description("Process")]
Process,
[Description("Reload")]
Reload,
[Description("Send")]
Send,
[Description("View")]
View
}
我的 ViewModel 中的属性:
/// <summary>
/// Bool denotes whether can display details
/// </summary>
private bool CanDisplayDetails
{
get
{
bool b = true;
if (SelectedItem != null)
{
if (SelectedItem.AdjustmentTypeID == 1)
{
b = false;
}
}
return b;
}
}
最佳答案
您的 Style
绑定(bind)使用的数据上下文是 ComboboxItem
的数据上下文(这将是枚举元素本身),而不是 View 模型,就像您一样希望。
尝试在绑定(bind)上使用相对源来遍历逻辑树并获取 ComboBox
的数据上下文,而不是 ComboBoxItem
。
<Setter Property="IsEnabled" Value="{Binding DataContext.CanDisplayDetails, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}"/>
您可以通过检查 Visual Studio 输出窗口自行诊断。您将看到一个绑定(bind)错误,告诉您类似的内容;
数据错误:在 _InvoiceActionsLong_ 实例上找不到 CanDisplayDetails 属性
编辑
为了使其仅适用于您的View
项目,请考虑;
- 自定义
StyleSelector
仅应用此样式的ComboBoxItem
的内容是View
。将ComboBox.ItemContainerStyleSelector
属性设置为选择器的实例。 - 一个
IMultiValueConverter
绑定(bind)到CanDisplayDetails
和枚举值的实现。如果值不是View
,此转换器将始终返回 true。
为什么会发生这种情况?
生成的 ItemSelector
项(例如 ComboBoxItem
)的数据上下文会自动设置为该项表示的数据。
关于c# - 如何在 MVVM 中禁用通过 ObjectProvider Enum WPF C# 提供的 ComboBoxItem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22379227/