【发布时间】:2012-03-08 13:49:50
【问题描述】:
我是 WPF 和自定义控件的新手。
我已经基于 Davids 示例在 VB 中使用 WPF 和 MVVM 实现了一个自定义控件:http://davidowens.wordpress.com/2009/02/18/wpf-search-text-box/
我有一个自定义控件库和一个对我的项目的引用来实现我的控件。 我通过 XAML 在视图中实现了我的控制:
编辑:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:l="clr-namespace:UIControls;assembly=UIControls"
mc:Ignorable="d"
x:Class="LoginView"
x:Name="LoginView"
Width="457" Height="216" Visibility="Visible" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.7*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<l:ExpandedTextBox Name="UsernameText" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,0,5,5" />
</Grid>
当我在一切正常后实例化我的自定义控件时,
<l:ExpandedTextBox Name="UsernameText" />
但是当我尝试在同一个视图中实例化它两次时,我得到一个错误代码:
Error 1 Cannot create an instance of "ExpandedTextBox"
编辑:
出现错误的 XAML 代码如下所示:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:l="clr-namespace:UIControls;assembly=UIControls"
mc:Ignorable="d"
x:Class="LoginView"
x:Name="LoginView"
Width="457" Height="216" Visibility="Visible" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.7*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<l:ExpandedTextBox Name="UsernameText" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,0,5,5" />
<l:ExpandedTextBox Name="Password" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,0,5,5" />
</Grid>
我将第二个自定义控件命名为不同的,而我的第一个自定义控件仍然可以正常工作。 该错误仅出现在第二个自定义控件“密码”中。
对应的 Generic.xaml 文件如下所示:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:UIControls">
<SolidColorBrush x:Key="ExpandedTextBox_Background" Color="White" />
<SolidColorBrush x:Key="ExpandedTextBox_Foreground" Color="Black" />
<LinearGradientBrush x:Key="ExpandedTextBox_Border" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFABADB3" Offset="0.05" />
<GradientStop Color="#FFE2E3EA" Offset="0.07" />
<GradientStop Color="#FFE3E9EF" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ExpandedTextBox_BorderMouseOver" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FF5C97C1" Offset="0.05" />
<GradientStop Color="#FFB9D7EB" Offset="0.07" />
<GradientStop Color="#FFC7E2F1" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="ExpandedTextBox_SearchIconBorder" Color="White" />
<SolidColorBrush x:Key="ExpandedTextBox_SearchIconBackground" Color="White" />
<LinearGradientBrush x:Key="ExpandedTextBox_SearchIconBorder_MouseOver" StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFFFFF" Offset="0" />
<GradientStop Color="#FFE5F4FC" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ExpandedTextBox_SearchIconBackground_MouseOver" StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFE7F5FD" Offset="0" />
<GradientStop Color="#FFD2EDFC" Offset="0.5" />
<GradientStop Color="#FFB6E3FD" Offset="0.51" />
<GradientStop Color="#FF9DD5F3" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ExpandedTextBox_SearchIconBorder_MouseDown" StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFFFFFFF" Offset="0" />
<GradientStop Color="#FFE5F4FC" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ExpandedTextBox_SearchIconBackground_MouseDown" StartPoint="0,0" EndPoint="0,1" >
<GradientStop Color="#FFE7F5FD" Offset="0" />
<GradientStop Color="#FFD2EDFC" Offset="0.5" />
<GradientStop Color="#FFB6E3FD" Offset="0.51" />
<GradientStop Color="#FF9DD5F3" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="ExpandedTextBox_LabelTextColor" Color="Gray" />
<Style x:Key="{x:Type l:ExpandedTextBox}" TargetType="{x:Type l:ExpandedTextBox}">
<Setter Property="Background" Value="{StaticResource ExpandedTextBox_Background}" />
<Setter Property="BorderBrush" Value="{StaticResource ExpandedTextBox_Border}" />
<Setter Property="Foreground" Value="{StaticResource ExpandedTextBox_Foreground}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="LabelText" Value="Username" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Text" Value="" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="LabelTextColor" Value="{StaticResource ExpandedTextBox_LabelTextColor}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:ExpandedTextBox}">
<Border x:Name="Border"
Padding="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid x:Name="LayoutGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}" />
</Grid.ColumnDefinitions>
<ScrollViewer x:Name="PART_ContentHost" Grid.Column="0" />
<Label x:Name="LabelText"
Grid.Column="0"
Foreground="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelTextColor}"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LabelText}"
Padding="2,0,0,0"
FontStyle="Italic" />
<Border x:Name="PART_SearchIconBorder"
Grid.Column="2"
Visibility="Collapsed"
BorderThickness="1"
Padding="1"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
BorderBrush="{StaticResource ExpandedTextBox_SearchIconBorder}"
Background="{StaticResource ExpandedTextBox_SearchIconBackground}">
<Image x:Name="SearchIcon"
Stretch="None"
Width="Auto"
Height="Auto"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="pack://application:,,,/UIControls;component/Images/clear.png" />
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource ExpandedTextBox_BorderMouseOver}" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource ExpandedTextBox_BorderMouseOver}" />
</Trigger>
<Trigger Property="HasText" Value="True">
<Setter Property="Visibility" TargetName="LabelText" Value="Hidden" />
<Setter Property="Visibility" TargetName="PART_SearchIconBorder" Value="Visible" />
</Trigger>
<Trigger Property="IsMouseOver" SourceName="PART_SearchIconBorder" Value="True">
<Setter Property="HasClicked" Value="True" />
<Setter Property="Background" TargetName="PART_SearchIconBorder" Value="#FFF0F5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
ExpandedTextBox VB 文件如下所示:
Imports System.Windows.Controls.Primitives
Imports System.ComponentModel
Public Class ExpandedTextBox
Inherits System.Windows.Controls.TextBox
Public Property LabelTextProperty As DependencyProperty = DependencyProperty.Register("LabelText", GetType(String), GetType(ExpandedTextBox))
Public Property LabelTextColorProperty As DependencyProperty = DependencyProperty.Register("LabelTextColor", GetType(Brush), GetType(ExpandedTextBox))
Public Property HasTextPropertyKey As DependencyProperty = DependencyProperty.Register("HasText", GetType(Boolean), GetType(ExpandedTextBox), New PropertyMetadata())
Public Property HasTextProperty As DependencyProperty = HasTextPropertyKey
Public Property HasClickedPropertyKey As DependencyProperty = DependencyProperty.Register("HasClicked", GetType(Boolean), GetType(ExpandedTextBox), New PropertyMetadata())
Public Property HasClickedProperty As DependencyProperty = HasClickedPropertyKey
Public Property HasClicked As Boolean
Get
Return CType(GetValue(HasClickedProperty), Boolean)
End Get
Set(ByVal value As Boolean)
SetValue(HasClickedProperty, value)
End Set
End Property
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Input.MouseButtonEventArgs)
If HasClicked = True Then
Me.Text = ""
Else
MyBase.OnMouseDown(e)
End If
End Sub
Public Property LabelText As String
Get
Return CType(GetValue(LabelTextProperty), String)
End Get
Set(ByVal value As String)
SetValue(LabelTextProperty, value)
End Set
End Property
Public Property LabelTextColor As Brush
Get
Return CType(GetValue(LabelTextColorProperty), Brush)
End Get
Set(ByVal value As Brush)
SetValue(LabelTextColorProperty, value)
End Set
End Property
Public Property HasText As Boolean
Get
Return CType(GetValue(HasTextProperty), Boolean)
End Get
Set(ByVal value As Boolean)
SetValue(HasTextProperty, value)
End Set
End Property
Shared Sub New()
DefaultStyleKeyProperty.OverrideMetadata(GetType(ExpandedTextBox), New FrameworkPropertyMetadata(GetType(ExpandedTextBox)))
End Sub
Protected Overrides Sub OnTextChanged(ByVal e As TextChangedEventArgs)
MyBase.OnTextChanged(e)
HasText = Text.Length <> 0
End Sub
End Class
为什么我不能在我的视图中创建两次相同的自定义控件?
提前致谢!
【问题讨论】:
-
没有理由可以将任意数量的用户控件副本添加到窗口中。这就是用户控制的重点!这里没有足够的代码来告诉你问题可能是什么。
-
您发布了很多信息,但没有包含引发错误的 XAML。
-
你可能在构造函数中做了一些你不能在同一个appdomain中做两次的事情。在 Visual Studio 的第二个实例中打开 UIControls.vbproj 并将调试器附加到第一个实例,然后尝试再次将两个 ExpandedTextBoxes 放在同一个视图上。
-
我用所有代码编辑了这个问题。希望这有助于理解有问题的人。再次提前感谢!
-
不知道有没有关系,但是依赖属性定义不应该是静态/共享的吗?
标签: wpf vb.net xaml mvvm custom-controls