【问题标题】:MultiBinding Converter Not Displaying ResultsMultiBinding 转换器不显示结果
【发布时间】:2019-01-13 16:00:41
【问题描述】:

作为学习在 WPF 中正确使用绑定的一部分,我创建了一个小型转换程序,将温度、长度、分数转换为小数等。一切都可以很好地处理温度和分数,因为这些都已完成使用简单的绑定和转换器。我遇到了长度转换的问题,因为它需要 MultiBinding 才能起作用。

对于控件,我使用两个文本框作为原始长度和转换后的长度。每一个都有一个匹配的组合框,用户可以在其中选择测量单位(即厘米、英寸、毫米等)。

使用断点,我已经确定条目正在到达 Convert 方法,并且方法内的代码正在正确计算所有内容。 result 变量甚至在方法调用结束时显示正确转换的数字,但该数字并没有返回到 lengthResult 文本框。

我已经尝试了我能想到的每一次迭代来让它工作,现在用谷歌搜索了大约 3 个小时。我找不到显示足够相似情况的问题或指南,我可以使它适用于这种情况。有人可以看看这个并找出我正在犯的(很可能)简单的错误吗?

注意:我在 C# 代码中有一个 ConvertBack 函数,但除了默认的 throw new NotImplementedException 之外,它还没有任何内容,所以我把它省略了。在Convert 首先工作之后,我会担心这一点。 :)

XAML:

<GroupBox Header="Length" DockPanel.Dock="Top">
        <GroupBox.Resources>
            <local:LengthConverter x:Key="lengthConverter" />
        </GroupBox.Resources>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Label Content="Original Length:" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" />
            <Label Content="Destination Length:" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="10" />
            <ComboBox x:Name="originUnitSelect" Grid.Column="2" Grid.Row="0" ItemsSource="{Binding Units}" Height="{Binding ElementName=lengthEntry, Path=ActualHeight}" MinWidth="50" />
            <ComboBox x:Name="destinationUnitSelect" Grid.Column="2" Grid.Row="1" ItemsSource="{Binding Units}" Height="{Binding ElementName=lengthResult, Path=ActualHeight}" MinWidth="50" />
            <TextBox x:Name="lengthEntry" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" Margin="10" HorizontalContentAlignment="Center" MinWidth="250" />
            <TextBox x:Name="lengthResult" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="10" HorizontalContentAlignment="Center" MinWidth="250">
                <TextBox.Text>
                    <MultiBinding Converter="{StaticResource lengthConverter}">
                        <Binding ElementName="lengthEntry" Path="Text" UpdateSourceTrigger="PropertyChanged" />
                        <Binding ElementName="originUnitSelect" Path="SelectedValue" />
                        <Binding ElementName="destinationUnitSelect" Path="SelectedValue" />
                    </MultiBinding>
                </TextBox.Text>
            </TextBox>
            <Button x:Name="convertLength" Grid.Column="1" Grid.Row="2" Content="Convert" VerticalAlignment="Center" HorizontalAlignment="Center" Click="convertLength_Click"  Margin="10"/>
        </Grid>
    </GroupBox>

C#:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        double result = 0.0;
        double cm_to_mm = 10;
        double cm_to_in = 0.3937;
        double cm_to_ft = 0.32808;
        double cm_to_yd = 0.010936;
        double mm_to_cm = 0.10;
        double mm_to_in = mm_to_cm * cm_to_in;
        double mm_to_ft = mm_to_cm * cm_to_ft;
        double mm_to_yd = mm_to_cm * cm_to_yd;
        double in_to_mm = 25.4;
        double in_to_cm = 2.54;
        double in_to_ft = 1 / 12;
        double in_to_yd = 1 / 36;
        double ft_to_yd = 36;
        double ft_to_in = 12;
        double ft_to_cm = ft_to_in * in_to_cm;
        double ft_to_mm = ft_to_in * in_to_mm;
        double yd_to_ft = 3;
        double yd_to_in = 36;
        double yd_to_cm = ft_to_in * in_to_cm;
        double yd_to_mm = ft_to_in * in_to_mm;


        if(values[1] != null && values[2] != null)
        {
            switch(values[1].ToString())
            {
                case "mm":
                    if (double.TryParse(values[0].ToString(), out result))
                    {
                        switch(values[2].ToString())
                        {
                            case "cm":
                                result = result * mm_to_cm;
                                break;
                            case "in":
                                result = result * mm_to_in;
                                break;
                            case "ft":
                                result = result * mm_to_ft;
                                break;
                            case "yd":
                                result = result * mm_to_yd;
                                break;
                        }
                        return result;
                    }
                    break;
                case "cm":
                    if(double.TryParse(values[0].ToString(), out result))
                    {
                        switch(values[2].ToString())
                        {
                            case "mm":
                                result = result * cm_to_mm;
                                break;
                            case "in":
                                result = result * cm_to_in;
                                break;
                            case "ft":
                                result = result * cm_to_ft;
                                break;
                            case "yd":
                                result = result * cm_to_yd;
                                break;
                        }
                        return result;
                    }
                    break;
                case "in":
                    if(double.TryParse(values[0].ToString(), out result))
                    {
                        switch(values[2].ToString())
                        {
                            case "mm":
                                result = result * in_to_mm;
                                break;
                            case "cm":
                                result = result * in_to_cm;
                                break;
                            case "ft":
                                result = result * in_to_ft;
                                break;
                            case "yd":
                                result = result * in_to_yd;
                                break;
                        }
                        return result;
                    }
                    break;
                case "ft":
                    if(double.TryParse(values[0].ToString(), out result))
                    {
                        switch(values[2].ToString())
                        {
                            case "mm":
                                result = result * ft_to_mm;
                                break;
                            case "cm":
                                result = result * ft_to_cm;
                                break;
                            case "in":
                                result = result * ft_to_in;
                                break;
                            case "yd":
                                result = result * ft_to_yd;
                                break;
                        }
                        return result;
                    }
                    break;
                case "yd":
                    if(double.TryParse(values[0].ToString(), out result))
                    {
                        switch(values[2].ToString())
                        {
                            case "mm":
                                result = result * yd_to_mm;
                                break;
                            case "cm":
                                result = result * yd_to_cm;
                                break;
                            case "in":
                                result = result * yd_to_in;
                                break;
                            case "ft":
                                result = result * yd_to_ft;
                                break;
                        }
                    }
                    break;
            }
        }
        return result;

        //throw new NotImplementedException();
    }

【问题讨论】:

  • 请注意,您的代码可以大大简化。进行两步转换,首先从源单位到标准单位米,然后从米到目标单位,可以省去过于复杂的嵌套 switch 语句。
  • 在第二步中,您应该创建一个仅以 SI 单位存储值的视图模型。然后,您将使用两个单独的转换器将视图模型属性绑定到输入和输出字段,这些转换器仅执行单个源/目标单位到 SI 单位的转换。
  • 感谢您的这些建议,我在想必须有一种更简单的方法来做到这一点,代码重复更少,但我想不出该怎么做。我想到的唯一方法是一系列方法,这些方法基本上可以替换一系列双常量(yd_to_ft、in_to_cm 等),但实际上会更长,只是更有条理,

标签: c# wpf data-binding converter multibinding


【解决方案1】:

textbox 需要一个字符串,而不是 double

return result.ToString();

应该做的伎俩。

【讨论】:

  • 我之前尝试过(现在再次仔细检查),它仍然以空的lengthResult TextBox结束。
  • 您是否为 ALLreturn result 语句执行此操作?你的转换器有很多东西
  • 是的,这就是问题所在。我只在最后一个更改了它,因为最终应该只有一个 return 语句。我从多个开始,然后意识到我可以将其降为一个(以避免这个确切的问题),并且在我稍后查看代码时显然跳过了它们。我知道这将是非常简单的事情,只是找不到。 :) 非常感谢!
  • 没问题!通常你只需要第二双眼睛就能看清一切。
  • 这是我的标准信条,也是为什么我知道这将是一个简单的解决方案。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
相关资源
最近更新 更多