自定义控件DigitTextBox编译报错:部分声明基类不一致
解决"Partial declarations of 'DigitTextBox' must not specify different base classes"错误
错误原因
你在ResourceDictionary上添加了x:Class="DigitEntryControl.DigitTextBox",编译器会自动生成一个继承自ResourceDictionary的partial类;但你的C#代码中DigitTextBox继承的是Control,同一个类的两个partial声明基类不一致,导致报错。
解决方案步骤
1. 移除ResourceDictionary中的x:Class属性
修改你的XAML资源文件,删除x:Class条目——自定义Control的样式资源不需要与Control类共享partial声明:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:DigitEntryControl"> <ControlTemplate x:Key="DigitMode" TargetType="{x:Type local:DigitTextBox}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Canvas> <TextBlock Text="{Binding SolidText}" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Canvas> </Border> </ControlTemplate> <ControlTemplate x:Key="HintMode" TargetType="{x:Type local:DigitTextBox}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <UniformGrid Visibility="{Binding TriSelect}" Columns="3"> <TextBlock Text="1"/> <TextBlock Text="2"/> <TextBlock Text="3"/> <TextBlock Text="4"/> <TextBlock Text="5"/> <TextBlock Text="6"/> <TextBlock Text="7"/> <TextBlock Text="8"/> <TextBlock Text="9"/> </UniformGrid> </Border> </ControlTemplate> <Style TargetType="{x:Type local:DigitTextBox}"> <Setter Property="Template" Value="{StaticResource HintMode}"/> <Style.Triggers> <Trigger Property="IsHintMode" Value="false"> <Setter Property="Template" Value="{StaticResource DigitMode}"/> </Trigger> </Style.Triggers> <!-- 通过EventSetter绑定按键事件 --> <EventSetter Event="PreviewKeyDown" Handler="DigitBox_PreviewKeyDown"/> </Style> </ResourceDictionary>
2. 在C#类中实现事件处理与接口成员
把按键处理方法添加到DigitTextBox类中,同时补全INotifyPropertyChanged接口的必要实现:
namespace DigitEntryControl { public partial class DigitTextBox : Control, INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; static DigitTextBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(DigitTextBox), new FrameworkPropertyMetadata(typeof(DigitTextBox))); BackgroundProperty.OverrideMetadata(typeof(DigitTextBox), new FrameworkPropertyMetadata(Brushes.White)); BorderBrushProperty.OverrideMetadata(typeof(DigitTextBox), new FrameworkPropertyMetadata(Brushes.Black)); BorderThicknessProperty.OverrideMetadata(typeof(DigitTextBox), new FrameworkPropertyMetadata(new Thickness(0.5))); WidthProperty.OverrideMetadata(typeof(DigitTextBox), new FrameworkPropertyMetadata(propertyChangedCallback: HeightWidthPropertyChanged)); HeightProperty.OverrideMetadata(typeof(DigitTextBox), new FrameworkPropertyMetadata(propertyChangedCallback: HeightWidthPropertyChanged)); } // 实现按键事件处理逻辑 private void DigitBox_PreviewKeyDown(object sender, KeyEventArgs e) { // 这里编写你的按键处理代码 } // 触发PropertyChanged事件的辅助方法 protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 补全尺寸变更回调方法 private static void HeightWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // 这里编写尺寸变更后的处理逻辑 } } }
3. 确保样式资源正确加载
如果你的ResourceDictionary不是默认的Themes/Generic.xaml,需要在应用启动时或控件所在程序集中显式引用该资源字典,保证样式能被框架正确识别。
额外说明
- 自定义WPF Control的样式通常推荐放在
Themes/Generic.xaml中,框架会自动查找并应用该文件中的样式。 - 使用
EventSetter绑定事件是WPF样式中处理控件事件的标准方式,避免模板内部直接绑定事件带来的上下文问题。
内容的提问来源于stack exchange,提问作者Nottoc
相关产品推荐
相关产品推荐

