我一直试图通过大量的谷歌搜索和SO来解决这个问题,但不幸的是我无法解决这个问题。我读的越多,我就越困惑。
我想将自动填充文本框构建为自定义控件。
我的CustomControl:
Array
我的守则背后:
<UserControl x:Class="ApplicationStyling.Controls.AutoCompleteTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ApplicationStyling.Controls"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
Name="AutoCompleteBox">
<Grid>
<TextBox Grid.Row="3"
Style="{DynamicResource InputBox}"
x:Name="SearchBox"
Text="{Binding Text}"
TextChanged="{Binding ElementName=AutoCompleteBox, Path=TextChanged}"/>
<ListBox x:Name="SuggestionList"
Visibility="Collapsed"
ItemsSource="{Binding ElementName=AutoCompleteTextBox, Path=SuggestionsSource}"
SelectionChanged="{Binding ElementName=AutoCompleteBox, Path=SelectionChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Label}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
最后,我使用它的方式:
using System.Collections;
using System.Windows;
using System.Windows.Controls;
namespace ApplicationStyling.Controls
{
/// <summary>
/// Interaction logic for AutoCompleteTextBox.xaml
/// </summary>
public partial class AutoCompleteTextBox : UserControl
{
public static readonly DependencyProperty SuggestionsSourceProperty;
public static readonly DependencyProperty TextProperty;
// Events
public static readonly RoutedEvent TextChangedProperty;
public static readonly RoutedEvent SelectionChangedProperty;
static AutoCompleteTextBox()
{
// Attributes
AutoCompleteTextBox.SuggestionsSourceProperty = DependencyProperty.Register("SuggestionsSource", typeof(IEnumerable), typeof(AutoCompleteTextBox));
AutoCompleteTextBox.TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteTextBox));
// Events
AutoCompleteTextBox.TextChangedProperty = EventManager.RegisterRoutedEvent("TextChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AutoCompleteTextBox));
AutoCompleteTextBox.SelectionChangedProperty = EventManager.RegisterRoutedEvent("SelectionChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AutoCompleteTextBox));
}
#region Events
public event RoutedEventHandler TextChanged
{
add { AddHandler(TextChangedProperty, value); }
remove { RemoveHandler(TextChangedProperty, value); }
}
// This method raises the Tap event
void RaiseTextChangedEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(AutoCompleteTextBox.TextChangedProperty);
RaiseEvent(newEventArgs);
}
public event RoutedEventHandler SelectionChanged
{
add { AddHandler(SelectionChangedProperty, value); }
remove { RemoveHandler(SelectionChangedProperty, value); }
}
// This method raises the Tap event
void RaiseSelectionChangedEvent()
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(AutoCompleteTextBox.SelectionChangedProperty);
RaiseEvent(newEventArgs);
}
#endregion
#region DProperties
/// <summary>
/// IEnumerable ItemsSource Property for the Suggenstion Box
/// </summary>
public IEnumerable SuggestionsSource
{
get
{
return (IEnumerable)GetValue(AutoCompleteTextBox.SuggestionsSourceProperty);
}
set
{
SetValue(AutoCompleteTextBox.SuggestionsSourceProperty, value);
}
}
/// <summary>
/// This is the Text attribute which routes to the Textbox
/// </summary>
public string Text
{
get
{
return (string)GetValue(AutoCompleteTextBox.TextProperty);
}
set
{
SetValue(AutoCompleteTextBox.TextProperty, value);
}
}
#endregion
public AutoCompleteTextBox()
{
InitializeComponent();
SearchBox.TextChanged += (sender, args) => RaiseTextChangedEvent();
SuggestionList.SelectionChanged += (sender, args) => RaiseSelectionChangedEvent();
}
}
}
其中<asc:AutoCompleteTextBox x:Name="ShareAutoCompleteBox"
Grid.Row="3"
SelectionChanged="ShareAutoCompleteBox_SelectionChanged"
TextChanged="ShareAutoCompleteBox_TextChanged"/>
是通过app.xaml加载的外包类库的命名空间。
无论如何,我在asc
属性的XAML中获得的问题以及运行代码时的问题:
System.InvalidCastException:无法将类型为“System.Reflection.RuntimeEventInfo”的对象强制转换为“System.Reflection.MethodInfo”。
那到底是怎么回事?我想将TextBox.TextChanged
转发到自定义控件模板中的AutoCompleteTextBox TextChanged
。与TextBox
的{{1}}相同。
我从https://msdn.microsoft.com/en-us/library/ms752288(v=vs.100).aspx(对于事件)和其他一些SO问题中获取了大部分代码,用于自定义属性的代码。
不确定,问题是什么,我期待着你的帮助。
答案 0 :(得分:0)
发生异常是因为您尝试将TextChanged
字段的值绑定到需要方法引用的属性。它的确实让WPF感到困惑。 :)
只需从XAML中的TextChanged
元素中删除TextBox
属性:
TextChanged="{Binding ElementName=AutoCompleteBox, Path=TextChanged}"
您已经在构造函数中订阅了该事件,这已经足够了。如果您确实想在构造函数中使用TextChanged
属性而不是订阅,那么您可以这样做,但是您需要提供一个实际的事件处理程序,例如代码隐藏中的一种方法。该方法只会调用RaiseTextChangedEvent()
方法,就像当前事件处理程序一样。它只是它在类中的命名方法而不是在构造函数中声明的匿名方法。
同样的事情适用于其他事件。
也就是说,您可能会重新考虑实施转发的事件。通常,您的控件的Text
属性将绑定到某个模型对象的属性,当绑定属性发生更改时,它本身可以做出适当的反应。它不应该在UserControl
对象上需要单独的事件来告诉它它的值已经改变。