WPF 切换 DataTemplate 中 UIElement 的可见性
我有一个 DataTemplate
定义如下,
<DataTemplate x:Key="PasswordViewerTemplate">
<StackPanel>
<TextBlock Text="{Binding PasswordChar, ElementName=this}"
Visibility="Visible" />
<TextBox Text="{Binding PasswordText}"
Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
我希望每次用户单击 TextBlock
和 TextBox
时都能够切换 TextBlock
和 TextBox
的可见性代码>StackPanel。我尝试在 StackPanel
上设置 MouseLeftButtonUp
事件处理程序,但这会引发异常
未将对象引用设置为对象实例
还有其他方法可以实现此目的吗?也许在 XAML 本身中使用触发器?
此外,这可能是相关的。上面的模板是模板选择器应用于 ListBox
的两个模板之一。 ListBox
本身位于 Grid
内,并且两个模板均在 Grid.Resources
部分中定义。
编辑1
我尝试按如下方式设置事件
<StackPanel MouseLeftButtonUp="OnPasswordViewerMouseLeftButtonUp">
...
</StackPanel>
private void OnPasswordViewerMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var sp = sender as StackPanel;
if( ( sp == null ) || ( sp.Children.Count != 2 ) ) {
return;
}
var passwordText = sp.Children[0] as TextBlock;
var plainText = sp.Children[1] as TextBox;
if( ( passwordText == null ) || ( plainText == null ) ) {
return;
}
passwordText.Visibility = ( passwordText.Visibility == Visibility.Visible ) ?
Visibility.Collapsed : Visibility.Visible;
plainText.Visibility = ( plainText.Visibility == Visibility.Visible ) ?
Visibility.Collapsed : Visibility.Visible;
}
I have a DataTemplate
defined as follows
<DataTemplate x:Key="PasswordViewerTemplate">
<StackPanel>
<TextBlock Text="{Binding PasswordChar, ElementName=this}"
Visibility="Visible" />
<TextBox Text="{Binding PasswordText}"
Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
I want to be able to toggle visibilities of the TextBlock
and the TextBox
each time the user clicks on the StackPanel
. I tried setting a MouseLeftButtonUp
event handler on the StackPanel
but this throws an exception
Object reference not set to an instance of an object
Is there another way to achieve this? Maybe in XAML itself using triggers?
Also, this might be relevant. The above template is one of two that is applied to a ListBox
by a template selector. The ListBox
itself is within a Grid
and both templates are defined within the Grid.Resources
section.
EDIT 1
I tried setting the event as follows
<StackPanel MouseLeftButtonUp="OnPasswordViewerMouseLeftButtonUp">
...
</StackPanel>
private void OnPasswordViewerMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var sp = sender as StackPanel;
if( ( sp == null ) || ( sp.Children.Count != 2 ) ) {
return;
}
var passwordText = sp.Children[0] as TextBlock;
var plainText = sp.Children[1] as TextBox;
if( ( passwordText == null ) || ( plainText == null ) ) {
return;
}
passwordText.Visibility = ( passwordText.Visibility == Visibility.Visible ) ?
Visibility.Collapsed : Visibility.Visible;
plainText.Visibility = ( plainText.Visibility == Visibility.Visible ) ?
Visibility.Collapsed : Visibility.Visible;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案之一是将
TextBox
和TextBlock
的可见性绑定到用作StackPanel 的
。下面是一个示例实现:DataContext
的类的属性Xaml 代码:
和 C# 代码:
One of the solutions is to bind visibility of the
TextBox
andTextBlock
to properties of the class which is used asDataContext
for theStackPanel
. Here is a sample implementation:Xaml code:
And C# code:
为什么不在视图模型中绑定项目的可见性?
一个例子。
在您的 ViewModel 中
以及您的鼠标事件中,您需要在堆栈面板内进行某种路由事件。一个例子:
在堆栈面板内,您将需要鼠标。无论你需要什么。阅读一些有关路由事件
示例的内容。如果
PreviewMouseLeftButtonUp
不起作用。在视图模型中
}
Why dont you bind the item's visibility in your view model?
an Example.
in your ViewModel say
and on your mouse event, you would need some sort of routed event inside the stack panel. an example:
inside the stack panel you would need mouse. whatever you need. read a little about routed events
Example. if
PreviewMouseLeftButtonUp
does not work.in the view model
}