在我创建了一个控件,该控件具有一个文本框和附加的文本更改事件处理程序 - 这是在 xaml 中。
问题:加载控件时,会触发文本更改事件,我不希望仅在加载控件时才发生,当我通过键入某些内容实际使其更改控件时。
你们专业人士建议我怎么做?:)
您所要做的就是在处理文本框之前在事件处理程序中检查文本框的 IsLoaded 属性。
事件处理程序附加到构造函数中的 InitializeComponent
方法之后,而不是在 Xaml
中。
即
public MainWindow()
{
InitializeComponent();
textBox1.TextChanged+=new TextChangedEventHandler(textBox1_TextChanged);
}
我
注意到您正在谈论用户控件,我唯一能想到的就是创建一个可用于禁止 TextChanged 事件的属性,直到父窗体完成加载。看看这样的东西是否有效。
MainForm Xaml:
<my:UserControl1 setInhibit="True" HorizontalAlignment="Left" Margin="111,103,0,0" x:Name="userControl11" VerticalAlignment="Top" Height="55" Width="149" setText="Hello" />
主表单 CS
private void Window_Loaded(object sender, RoutedEventArgs e)
{
userControl11.setInhibit = false;
}
用户控件:
public UserControl1()
{
InitializeComponent();
textBox1.TextChanged += new TextChangedEventHandler(textBox1_TextChanged);
}
public string setText
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
public bool setInhibit { get; set; }
void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
if (setInhibit) return;
// Do your work here
}
UserControl1.xaml:
<Grid>
<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" TextChanged="TextBox_TextChanged"/>
</Grid>
其中 TextChanged 是 TextBox 的原始事件
UserControl1.xaml.cs:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
_isFirstTime = true;
DataContext = this;
InitializeComponent();
}
public event TextChangedEventHandler TextBoxTextChanged;
bool _isFirstTime;
//MyText Dependency Property
public string MyText
{
get { return (string)GetValue(MyTextProperty); }
set { SetValue(MyTextProperty, value); }
}
public static readonly DependencyProperty MyTextProperty =
DependencyProperty.Register("MyText", typeof(string), typeof(UserControl1), new UIPropertyMetadata(""));
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (TextBoxTextChanged != null)
if (!_isFirstTime)
{
TextBoxTextChanged(sender, e);
}
_isFirstTime = false;
}
}
其中TextBox_TextChanged是原始文本更改的自定义事件处理程序而 TextBoxTextChanged 更像是原始 TextChanged 的包装器
Window.xaml:
<Grid>
<c:UserControl1 TextBoxTextChanged="TextBoxValueChanged"/>
</Grid>
如您所见,您可以将事件处理程序添加到事件包装器(TextBoxTextChanged)
Window.xaml.cs:
private void TextBoxValueChanged(object sender, TextChangedEventArgs e)
{
MessageBox.Show("asd");
}
最后,第一次更改文本时不会触发文本框值更改
private void TextBoxValueChanged(object sender, TextChangedEventArgs e)
{
if (Textbox1.IsFocused)
{
App.Current.Properties["TextChanged"] = "1"; // Set Flag
}
}
private void TextBoxLostFocus(object sender, RoutedEventArgs e)
{
if (App.Current.Properties["TextChanged"] == "1")
{
// Do Your Wor Here
App.Current.Properties["TextChanged"] = "0"; // Clear Flag
}
}
在 XAML 上:
<TextBox xName="TextBox1" LostFocus="TextBoxLostFocus" TextChanged="TextBoxValueChanged"/>
(这是一个非常基本,肮脏的代码隐藏黑客...检查 IsLoaded 属性,如布伦特所述,我发现是有效的)
在这里,由于在创建文本框控件时它没有焦点,TextChanged 事件将触发,但标志"1"未设置......稍后当用户在编辑后离开字段时,由于它具有焦点,因此设置了标志... 将触发 LostFocus,但如果文本框已更改,则仅触发运行代码。
我找到了一种方法来防止跨多个输入的这种行为,而无需为每个输入创建一个唯一的布尔值......
private void TextChanged_UpdateItem(object sender, TextChangedEventArg e)
{
TextBox txtBox = sender as TextBox;
if (!txtBox.IsFocused)
return;
//The rest of your code here
}
所以基本上,如果文本字段没有焦点(如初始化),它只会返回。这也可以防止它在数据在其他位置更改时触发。:)
或者,正如布伦特所提到的,你可以只寻找"IsLoaded":
private void TextChanged_UpdateItem(object sender, TextChangedEventArg e)
{
TextBox txtBox = sender as TextBox;
if (!txtBox.IsLoaded)
return;
//The rest of your code here
}