大佬们救命啊,IValueConverter实在无法理解:为什么Type明明是个枚举类型,返回确实String

千梦一生 2020-06-08 01:10:36


wpf程序中某部分

像上图这样,targetType我看了要求返回一个枚举类型,

这代码是前辈写的,实在无法理解为什么返回的却是【与其中某枚举值同名的字符串】。

我也试过直接 把字符串赋值给这个枚举类型的变量,然鹅报错了

请大佬们帮帮我吧
...全文
454 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
千梦一生 2020-06-12
  • 打赏
  • 举报
回复
谢谢大家的讨论、及建议。
普通的转换用法基本的我能够实现。就可惜像这位前辈写的代码有些搞不懂。
虽然还是没搞明白为何能这么搞,不过还是谢谢大家 不吝帮助。
github_36000833 2020-06-09
  • 打赏
  • 举报
回复
引用 10 楼 千梦一生 的回复:
... 第一个参数是bool符合预期。但我看它返回值直接.ToString()。感到无法理解【看上去从bool转到了string,但实际上应当是bool到ERemoteCtrlType啊】。
理解了IValueConverter是用来做什么的,就理解了如何去实现Convert和ConvertBack。 比如界面上的CheckBox,它的IsChecked属性的类型是bool?。如果我们要绑定到CheckBox.IsChecked,那么就要支持从 ERemoteCtrlType -> bool?的转换(Convert,数据源显示到界面上),以及 bool? -> ERemoteCtrlType (ConvertBack,界面更新到数据源)。 比如界面上用了TextBox,如果我们要绑定到TextBox.Text,它的类型就是string,那么就要支持从 ERemoteCtrlType -> string的转换(Convert,数据源显示到界面上),以及 string -> ERemoteCtrlType (ConvertBack,界面更新到数据源)。

<Window x:Class="..." />
    </Window.Resources>
    <StackPanel>
        <CheckBox IsChecked="{Binding m_iRemoteCtrl, Converter={StaticResource RemoteCtrlTypeConverter}}">Remote Control</CheckBox>
        <TextBox Text="{Binding m_iRemoteCtrl, Converter={StaticResource RemoteCtrlTypeConverter}}" />
        <TextBox Text="观察类型转换" />
    </StackPanel>
</Window>
public class RemoteCtrlTypeConverter : IValueConverter
{
    // 转换成其他类型
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ERemoteCtrlType)
        {
            ERemoteCtrlType remoteControlType = (ERemoteCtrlType)value;

            // Checkbox需要一个bool, 或者一个bool?(当他支持三状态的时候)
            if (targetType == typeof(bool) || targetType == typeof(bool?))
            {
                return remoteControlType == ERemoteCtrlType.ERemoteCtrlType_Remote;
            }

            // TextBox需要一个string
            if (targetType == typeof(string))
            {
                return System.Convert.ToString(remoteControlType, culture);
            }
        }
        throw new NotSupportedException(); // 其他转换暂不支持
    }

    // 从其他类型转换回来
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (targetType == typeof(ERemoteCtrlType))
        {
            // CheckBox会给出boolean,把bool转换为为ERemoteCtrlType。假定True的时候为Remote。
            if (value is bool || value is bool?)
            {
                return (bool?)value == true
                    ? ERemoteCtrlType.ERemoteCtrlType_Remote
                    : ERemoteCtrlType.ERemoteCtrlType_Local;
            }

            ERemoteCtrlType result;
            // TextBox会给出string,把string解析为ERemoteCtrlType枚举
            if (value is string && Enum.TryParse(value as string, ignoreCase: true, result: out result))
            {
                return result;
            }

            return default(ERemoteCtrlType);
        }
        throw new NotSupportedException(); // 其他转换暂不支持
    }
}
  • 打赏
  • 举报
回复
哦,是 WPF。微软的 WPF这么好的东西,吃亏就吃亏在将近10年了都不把一大堆动态定义诡异改变类型的 object 函数改成强类型容易调试的东西,把学习曲线变得异常诡异陡峭,没人愿意学。
  • 打赏
  • 举报
回复
设计程序时切忌要禁止乱定义 object 类型变量和返回值,要用强类型编程,免得乱报各种问题。
千梦一生 2020-06-08
  • 打赏
  • 举报
回复
引用 8 楼 wanghui0380 的回复:


引用 9 楼 Bridge_go 的回复:


两位老师好,因为原代码运行正确。但不能理解。
我看原来的代码,将isChecked这个bool绑定在了m_iRemoteCtrl属性上

public enum ERemoteCtrlType : byte //远程控制
{
ERemoteCtrlType_Local = 0x00,//本控
ERemoteCtrlType_Remote = 0x01,// 远控

}
/////////////////////////////////////////////////////////////////////
public ERemoteCtrlType m_iRemoteCtrl
{
get { return _m_iRemoteCtrl; }
set
{
_m_iRemoteCtrl = value;
NPC(pca_m_iRemoteCtrl);
}
}
ERemoteCtrlType _m_iRemoteCtrl;
static readonly PropertyChangedEventArgs pca_m_iRemoteCtrl = new PropertyChangedEventArgs("m_iRemoteCtrl");


我调试观察了一会儿,这个转换发生在set之前。就怀疑ConvertBack【将bool类型转换为ERemoteCtrlType枚举类型】。
第一个参数是bool符合预期。但我看它返回值直接.ToString()。感到无法理解【看上去从bool转到了string,但实际上应当是bool到ERemoteCtrlType啊】。
Bridge_go 2020-06-08
  • 打赏
  • 举报
回复
这value只能是bool,不然就报错的吧 还不如直接点

public ERemoteCtrlType  ConvertBack(bool value)
{
   return value ? ERemoteCtrlType.ERemoteCtrlType_Remote : ERemoteCtrlType.ERemoteCtrlType_Local;
}
wanghui0380 2020-06-08
  • 打赏
  • 举报
回复
上述代码没有意义,你就告诉我们,你现在要实现什么把。 你想要实现什么?
wanghui0380 2020-06-08
  • 打赏
  • 举报
回复
Retrun b; 话说这代码到底啥作用啊。 貌似没有任何作用。 你说绑定也好,序列化也罢,打印也罢。其实默认都是调用 tostring,所以这个代码看上去没啥意义 尤其那个targertype,压根就木用到?只用了value和param??
千梦一生 2020-06-08
  • 打赏
  • 举报
回复
引用 5 楼 千梦一生 的回复:
几位老师好,这个更具体是这样的情况。
在ui上有一个RadioButton。IsChecked被Binding到了某类型地属性上


而ERemoteCtrlType正是一个枚举类型:


这里我发现他把isChecked的bool转换成了 public enum ERemoteCtrlType : byte 这个类型。
我找了一下他的CheckConverter,如下:





[quote=引用 1 楼 OrdinaryCoder 的回复:]


引用 2 楼 github_36000833 的回复:


引用 3 楼 正怒月神 的回复:



引用 4 楼 Bridge_go 的回复:
[/quote]
打断点时,运行看到的targetType是 枚举类型。传入的parameter是xaml中设置的 枚举值之一【的字符串表示形式】
千梦一生 2020-06-08
  • 打赏
  • 举报
回复


几位老师好,这个更具体是这样的情况。
在ui上有一个RadioButton。IsChecked被Binding到了某类型地属性上


而ERemoteCtrlType正是一个枚举类型:


这里我发现他把isChecked的bool转换成了 public enum ERemoteCtrlType : byte 这个类型。
我找了一下他的CheckConverter,如下:





引用 1 楼 OrdinaryCoder 的回复:


引用 2 楼 github_36000833 的回复:


引用 3 楼 正怒月神 的回复:



引用 4 楼 Bridge_go 的回复:
Bridge_go 2020-06-08
  • 打赏
  • 举报
回复
没看懂这方法干嘛的
正怒月神 2020-06-08
  • 打赏
  • 举报
回复
你看方法逻辑。 很明显,return b。这个b是string。
github_36000833 2020-06-08
  • 打赏
  • 举报
回复
引用 楼主 千梦一生 的回复:
... 这代码是前辈写的,实在无法理解为什么返回的却是【与其中某枚举值同名的字符串】。 ...
不用迷信“前辈”。 错误的代码,不论谁写的,还是错误的代码。 返回枚举,可以用Enum.Parse(...)。
OrdinaryCoder 2020-06-08
  • 打赏
  • 举报
回复
return b; b的声明是 string b =XX; 不返回string返回什么呢

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧