C# Can';t将MS.Internal.NamedObject类型的对象转换为System.Windows.Datatemplate
我想更改基于枚举的图标 我已经为我的UserControl创建了一个名为CallControlViewModel的新viewmodelC# Can';t将MS.Internal.NamedObject类型的对象转换为System.Windows.Datatemplate,c#,wpf,C#,Wpf,我想更改基于枚举的图标 我已经为我的UserControl创建了一个名为CallControlViewModel的新viewmodel public class CallControlViewModel : BaseViewModel { private InputTypeEnum _inputTypeEnum; public CallControlViewModel() { } public InputTypeEnum InputType
public class CallControlViewModel : BaseViewModel
{
private InputTypeEnum _inputTypeEnum;
public CallControlViewModel()
{
}
public InputTypeEnum InputType
{
get { return _inputTypeEnum; }
set
{
if (_inputTypeEnum != value)
{
_inputTypeEnum = value;
NotifyPropertyChanged("InputType");
}
}
}
}
这是baseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Notify of Property Changed event
/// </summary>
/// <param name="propertyName"></param>
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
用户控制背后的代码
public partial class CallControl : UserControl
{
private CallControlViewModel callControlViewModel;
public CallControl()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(CallControl_Loaded);
}
void CallControl_Loaded(object sender, RoutedEventArgs e)
{
callControlViewModel = new CallControlViewModel();
this.DataContext = callControlViewModel;
}
private void CallBox_TextChanged(object sender, TextChangedEventArgs e)
{
InputTypeEnum type = DecideInputType();
callControlViewModel.InputType = type;
}
private InputTypeEnum DecideInputType()
{
if(string.IsNullOrEmpty(CallBox.Text))
{
return InputTypeEnum.Empty;
}
if (IsNumeric(CallBox.Text))
{
return InputTypeEnum.Number;
}
return InputTypeEnum.Text;
}
这是我的Xaml:
<UserControl.Resources>
<Style x:Key="InputTypeIndicatorStyle" TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding InputType}" Value="0">
<Setter Property="ContentTemplate" Value="{StaticResource ResourceKey=NumberIndicator}" />
</DataTrigger>
<DataTrigger Binding="{Binding InputType}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource ResourceKey=NumberIndicator}" />
</DataTrigger>
<DataTrigger Binding="{Binding InputType}" Value="2">
<Setter Property="ContentTemplate" Value="{StaticResource ResourceKey=TextIndicator}" />
</DataTrigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="NumberIndicator">
<Border x:Name="CallIconBorder" Width="35" BorderThickness="1,0,0,0" Background="#353535"
BorderBrush="#5d5d5d" MouseLeftButtonDown="CallIconBorder_MouseLeftButtonDown" Style="{StaticResource CallBorderStyle}" >
<Image StretchDirection="DownOnly" Margin="5" Source="/Image/call.png"/>
</Border>
</DataTemplate>
<DataTemplate x:Key="TextIndicator">
<Border x:Name="SearchIconBorder" Width="35" >
<Image StretchDirection="DownOnly" Margin="5" Source="/Image/search.png"/>
</Border>
</DataTemplate>
</UserControl.Resources>
<DockPanel x:Name="CallControlDock" VerticalAlignment="Bottom" Background="{StaticResource LightGrey}" Height="30">
<ContentControl Style="{StaticResource InputTypeIndicatorStyle}" DockPanel.Dock="Right" HorizontalAlignment="Right" />
<Border x:Name="ClearIconBorder" DockPanel.Dock="Right" Width="20" Visibility="Hidden" VerticalAlignment="Center" Margin="5,0,5,0"
MouseDown="ClearIconBorder_MouseDown" Style="{StaticResource ClearIconStyle}" Opacity="0.5">
<Image StretchDirection="DownOnly" Source="/Image/close.png" HorizontalAlignment="Left"/>
</Border>
<spinners:ucSpinnerCogs x:Name="LoadSpinner" DockPanel.Dock="Right" HorizontalAlignment="Right" Visibility="Collapsed" />
<TextBox x:Name="CallBox" TextWrapping="Wrap" FontSize="14" FontFamily="Segoe UI Semibold" HorizontalAlignment="Stretch"
Foreground="{StaticResource AlmostWhite}" VerticalAlignment="Center"
GotFocus="CallBox_GotFocus" LostFocus="CallBox_LostFocus" TextChanged="CallBox_TextChanged" KeyDown="CallBox_KeyDown"
MouseRightButtonDown="CallBox_MouseRightButtonDown"
ContextMenu="{x:Null}">
</TextBox>
</DockPanel>
InvalidCastException,无法转换类型为的对象
MS.Internal.NamedObject to System.Windows.Datatemplate
我做错了什么 我确实记得几年前一个项目中的这个问题。我们遇到了同样的问题,并添加了代码来拦截,如下所示:
/// <summary>
/// Tests whether the object is the 'NamedObject'. This is placed into 'DataContext' sometimes by WPF as a dummy.
/// </summary>
public static bool IsNamedObject(this object obj)
{
return obj.GetType().FullName == "MS.Internal.NamedObject";
}
//
///测试对象是否为“NamedObject”。WPF有时将其作为虚拟对象放入“DataContext”中。
///
公共静态bool IsNamedObject(此对象obj)
{
返回obj.GetType().FullName==“MS.Internal.NamedObject”;
}
我们在论坛上发布了一些关于这个的问题,但从来没有得到真正的答案。对了,这篇文章是一条杂乱无章的红鲱鱼。。。对于任何不熟悉这句话的人来说,这意味着你可以忘记所有给出的错误,因为当这是正确的,你不会得到错误。。。这是误导 所以我们走吧。。。使用
触发器
方法:
首先,这里有一个枚举
:
public enum TestEnum
{
None, One, Two, Three
}
现在,属性:
private TestEnum enumInstance = TestEnum.None;
public TestEnum EnumInstance
{
get { return enumInstance; }
set { enumInstance = value; NotifyPropertyChanged("EnumInstance"); }
}
private ObservableCollection<TestEnum> enumCollection =
new ObservableCollection<TestEnum>() { TestEnum.None, TestEnum.One,
TestEnum.Two, TestEnum.Three };
public ObservableCollection<TestEnum> EnumCollection
{
get { return enumCollection; }
set { enumCollection = value; NotifyPropertyChanged("EnumCollection"); }
}
private TestEnum enumInstance=TestEnum.None;
公共TestEnumEnumInstance
{
获取{返回枚举实例;}
设置{enumInstance=value;NotifyPropertyChanged(“enumInstance”);}
}
私有ObservableCollection枚举集合=
新的ObservableCollection(){TestEnum.None,TestEnum.One,
TestEnum.2,TestEnum.3};
公共可观测集合枚举集合
{
获取{return enumCollection;}
设置{enumCollection=value;NotifyPropertyChanged(“enumCollection”);}
}
现在,XAML:
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Width="16" Height="16" Stretch="None" Margin="0,0,0,20">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding EnumInstance}" Value="One">
<Setter Property="Image.Source" Value="/WpfApplication2;component/Images/Copy_16.png" />
</DataTrigger>
<DataTrigger Binding="{Binding EnumInstance}" Value="Two">
<Setter Property="Image.Source" Value="/WpfApplication2;component/Images/Edit_16.png" />
</DataTrigger>
<DataTrigger Binding="{Binding EnumInstance}" Value="Three">
<Setter Property="Image.Source" Value="/WpfApplication2;component/Images/CloseRed_16.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ComboBox ItemsSource="{Binding EnumCollection}" SelectedItem="{Binding EnumInstance}" />
</StackPanel>
我相信您可以将此代码转移到您的项目中。最后要注意的是。。。如果您有更多的
enum
值,您最好创建一个enumtoboolmagesourceconverter
,并用它绑定。适用于遇到相同问题但没有找到其他答案的所有人,这些答案有助于查找到底发生了什么
当您尝试在资源声明之前使用StaticResource
引用资源时,会出现此问题
在这个问题中,这些资源是NumberIndicator
和textdindicator
这是因为StaticResource
在编译时工作,不能向前看。因此,要解决这个问题,您可以将资源移动到尚未引用的位置。或者只使用运行时DynamicResource
我做错了什么?
-你把太多的代码放在了不该放的地方。又回到了破球任务上,嗯@HighCore?:)有趣的是,当我这么做的时候,每个人都对我不屑一顾,所以我放弃了。。。不过,我很高兴有人坚持下去@HighCore你能举个例子说明什么不属于你吗?我还是从wpf开始,所以我想学习。伙计,他不是说你展示了太多的代码,就是说你为这么简单的需求写了太多的代码。他只是想掌握一些东西。救救他!谢谢你的明确的例子!我可以将此代码移植到我的代码中。您摘要中的信息来自何处?NamedObject
类型来自DependencyProperty.UnsetValue
,(来自公共.NET源代码)。
private TestEnum enumInstance = TestEnum.None;
public TestEnum EnumInstance
{
get { return enumInstance; }
set { enumInstance = value; NotifyPropertyChanged("EnumInstance"); }
}
private ObservableCollection<TestEnum> enumCollection =
new ObservableCollection<TestEnum>() { TestEnum.None, TestEnum.One,
TestEnum.Two, TestEnum.Three };
public ObservableCollection<TestEnum> EnumCollection
{
get { return enumCollection; }
set { enumCollection = value; NotifyPropertyChanged("EnumCollection"); }
}
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Width="16" Height="16" Stretch="None" Margin="0,0,0,20">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding EnumInstance}" Value="One">
<Setter Property="Image.Source" Value="/WpfApplication2;component/Images/Copy_16.png" />
</DataTrigger>
<DataTrigger Binding="{Binding EnumInstance}" Value="Two">
<Setter Property="Image.Source" Value="/WpfApplication2;component/Images/Edit_16.png" />
</DataTrigger>
<DataTrigger Binding="{Binding EnumInstance}" Value="Three">
<Setter Property="Image.Source" Value="/WpfApplication2;component/Images/CloseRed_16.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<ComboBox ItemsSource="{Binding EnumCollection}" SelectedItem="{Binding EnumInstance}" />
</StackPanel>