【问题标题】:Unable to cast object in WPF MultiValueConverter无法在 WPF MultiValueConverter 中转换对象
【发布时间】:2016-01-25 09:21:33
【问题描述】:

我正在努力学习MultiBinding。 我尝试将两个值(一个 double 和一个 boolean)从 viewmodel 传递给转换器并返回一个 string 结果。

XAML

<TextBlock>
     <TextBlock.Text>
         <MultiBinding Converter="{StaticResource MyValueConverter}">
              <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.PowerValue" />
              <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.IsPowerAvailable" />
         </MultiBinding>
     </TextBlock.Text>
</TextBlock>

转换器

class MyValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (System.Convert.ToBoolean(values[1]))
        {
            return string.Format("{0:n1}", values[0]); 
        }
        else
        {
            return "[not available]";
        }
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

视图模型

public double PowerValue
public bool IsPowerAvailable

在转换器中我会得到一个异常Unable to cast object of type 'MS.Internal.NamedObject' to type 'System.IConvertible

这是什么意思?我是否错误地实现了MultiBinding

编辑:

ViewModel 看起来像这样

class CarViewModel : ViewModelBase
{
    private car _selectedCar;
    public car SelectedCar
    {
        get { return _selectedCar; }
        set
        {
            _selectedCar = value;
        }
    }

模型如下所示:

class car 
{
    public double PowerValue { get; set; }
    public bool IsPowerAvailable{ get; set; }
}

【问题讨论】:

  • 您可能会在此类似主题中找到一些提示:stackoverflow.com/questions/18866308/…
  • 你为什么使用 relativeSource ?你有不同的数据上下文吗?
  • 不,我只有一个数据上下文。我尝试了很多替代方案,也没有RelativeSource,但它们也不起作用
  • 这个文本块在哪里使用?只是在窗口/用户控件内还是在数据模板内?
  • TextBlock 是独立的 ScrollViewer 并且在 Grid 中。没有数据模板。

标签: c# wpf imultivalueconverter


【解决方案1】:

例外是由于无法访问DataContext.SelectedCar.IsPowerAvailable,请确保SelectedCar 属性确实可以从ScrollViewer DataContext 访问,这里是一个工作示例

 Title="MainWindow" Height="350" Width="525" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
    <wpfApplication12:MyValueConverter x:Key="MyValueConverter"/>
</Window.Resources>
<Grid>      
  <ScrollViewer>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource MyValueConverter}">
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.PowerValue" />
                    <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ScrollViewer}" Path="DataContext.SelectedCar.IsPowerAvailable" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </ScrollViewer>
</Grid>

并且 selectedCar 是在 VM/CodeBhind 中定义的:

private Car _selectedCar = new Car()
    {
        IsPowerAvailable = true,
        PowerValue = 14
    };
    public Car SelectedCar
    {
        get
        {
            return _selectedCar;
        }

        set
        {
            if (_selectedCar == value)
            {
                return;
            }

            _selectedCar = value;                
        }
    }

【讨论】:

  • 如果无法达到 DataContext.SelectedCar.IsPowerAvailable 为什么我可以通过将绑定更改为 Text="{Binding SelectedCar.PowerValue, Mode=OneWay, StringFormat=n1}" (还编辑了初始帖子以显示视图模型和模型)
  • by Text="{Binding SelectedCar..您正在使用 TextBlock DataContext,在您提供的示例中您使用的是 ScrollViewer DataContextx (..AncestorType=ScrollViewer),请确保您的 ScrollViewer 的 DataContext 是正确设置!,如果是这样,请告诉我你完整的 xaml
  • 在我的 UserControl 中,我设置了 并且 datacontext 没有在其他任何地方设置。 TextBlock 在 ScrollViewver 内
  • 只使用没有 relativeResouce 的绑定,它应该可以工作。
  • 嗯,上面的代码对我来说很好,我已经根据你的描述复制了一个示例,确保没有错字或任何错误!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
相关资源
最近更新 更多