ydoudou 2024-05-20 15:29 采纳率: 33.3%
浏览 3

wpf combobox

WPF ComboBox ItemTemplate Binding 更新问题

程序运行起来第一次能执行到enumDescriptionConverter,如果用户点击OK按钮之后怎样才能再次触发Converter,以下是xaml和CS代码。

<ComboBox Width="200" Height="50" Margin="100"
          HorizontalAlignment="Center"
          VerticalAlignment="Center"
          ItemsSource="{Binding AlarmLevelList, UpdateSourceTrigger=PropertyChanged}"
          SelectedItem="{Binding SelectedAlarmLevel}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

<Button Content="OK" Width="100" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"/>
public enum AlarmLevel
{
    [Description("正常")]
    Normal = 0,

    [Description("警报")]
    Warring = 1,

    [Description("故障")]
    Error = 2,
}

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        InitList();
    }

    public List<AlarmLevel> AlarmLevelList
    {
        get
        {
            return _alarmLevelList;
        }
        set
        {
            _alarmLevelList = value;
            DoPropertyChanged(AlarmLevelListPropertyName);
        }
    }

    private List<AlarmLevel> _alarmLevelList;
    public const string AlarmLevelListPropertyName = "AlarmLevelList";

    public AlarmLevel SelectedAlarmLevel
    {
        get { return _selectedAlarmLevel; }
        set
        {
            if (_selectedAlarmLevel != value)
            {
                _selectedAlarmLevel = value;
                DoPropertyChanged(SelectedAlarmLevelPropertyName);
            }
        }
    }
    private AlarmLevel _selectedAlarmLevel;
    public const string SelectedAlarmLevelPropertyName = "SelectedAlarmLevel";


    public void InitList()
    {
        AlarmLevelList = new List<AlarmLevel>();
        AlarmLevelList.Add(AlarmLevel.Normal);
        AlarmLevelList.Add(AlarmLevel.Warring);
        AlarmLevelList.Add(AlarmLevel.Error);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        DoPropertyChanged(AlarmLevelListPropertyName);
        DoPropertyChanged(SelectedAlarmLevelPropertyName);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void DoPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class EnumDescriptionConverter : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null && value as string != "")
        {
            Enum myEnum = (Enum)value;
            string description = GetEnumDescription(myEnum);
            return description;
        }

        return "";
    }

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

    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;
        }
    }
}
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-20 15:29
    关注

    引自免费微信小程序:皆我百晓生

    在您的代码中,当用户点击"OK"按钮时,并没有实际更新AlarmLevelListSelectedAlarmLevel的值,因此转换器不会被重新调用。为了使转换器在点击"OK"按钮后重新执行,您可以考虑在Button_Click事件处理函数中更改列表内容或选定项。

    这里是一个修改后的Button_Click方法示例,它会改变选定的报警级别并添加一个新的报警级别到列表中,从而触发enumDescriptionConverter的转换逻辑:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // 更改选定的报警级别(例如从Normal变为Warring)
        if (SelectedAlarmLevel == AlarmLevel.Normal)
        {
            SelectedAlarmLevel = AlarmLevel.Warring;
        }
        else if (SelectedAlarmLevel == AlarmLevel.Warring)
        {
            SelectedAlarmLevel = AlarmLevel.Error;
        }
        else
        {
            SelectedAlarmLevel = AlarmLevel.Normal;
        }
    
        // 向列表中添加一个新项目(这将导致ItemsSource更新)
        AlarmLevelList.Add((AlarmLevel)(((int)AlarmLevel.ListMax) + 1));
    
        // 触发PropertyChanged通知,这将使ComboBox重新评估其数据绑定
        DoPropertyChanged(SelectedAlarmLevelPropertyName);
        DoPropertyChanged(AlarmLevelListPropertyName);
    }
    

    这段代码首先更改了选定的报警级别,然后向AlarmLevelList中添加了一个新的项目(这个项目是当前枚举最大值加一)。这将强制ComboBox更新其显示,从而再次触发enumDescriptionConverter

    同时,在InitList方法中,您可能需要确保AlarmLevel.ListMax这样的值不存在,否则可以创建一个新的枚举值。如果ListMax不存在,可以简单地为新项目添加一个临时名称,例如:

    // 添加新项目
    AlarmLevelList.Add(new AlarmLevel?(new int?(AlarmLevel.Error.Value + 1)).HasValue ? (AlarmLevel)(AlarmLevel.Error.Value + 1) : (AlarmLevel?)null);
    

    这样做的目的是确保不会抛出异常,因为枚举类型通常不支持大于现有最大值的新值。如果您确实想要在枚举中添加新值,请确保在枚举中定义它。

    请注意,这个示例仅用于演示如何触发转换器的重新执行。根据您的具体需求,您可能需要调整Button_Click方法中的行为。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月20日

悬赏问题

  • ¥200 csgo2的viewmatrix值是否还有别的获取方式
  • ¥15 Stable Diffusion,用Ebsynth utility在视频选帧图重绘,第一步报错,蒙版和帧图没法生成,怎么处理啊
  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上