我的DataTemplate
定义如下
<DataTemplate x:Key="PasswordViewerTemplate">
<StackPanel>
<TextBlock Text="{Binding PasswordChar, ElementName=this}"
Visibility="Visible" />
<TextBox Text="{Binding PasswordText}"
Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
每次用户点击TextBlock
时,我希望能够切换TextBox
和StackPanel
的可见性。我尝试在MouseLeftButtonUp
上设置StackPanel
事件处理程序,但这会引发异常
Object reference not set to an instance of an object
还有另一种方法可以达到这个目的吗?也许在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;
}
答案 0 :(得分:1)
其中一个解决方案是将TextBox
和TextBlock
的可见性绑定到类的属性,该属性用作DataContext
的{{1}}。以下是一个示例实现:
Xaml代码:
StackPanel
和C#代码:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="PasswordViewerTemplate">
<StackPanel PreviewMouseUp="StackPanel_PreviewMouseUp">
<TextBlock Text="{Binding Path=PasswordChar}"
Visibility="{Binding Path=TextBlockVisibility}" />
<TextBox Text="{Binding Path=PasswordText}"
Visibility="{Binding Path=TextBoxVisibility}" />
</StackPanel>
</DataTemplate>
</Grid.Resources>
<ListBox x:Name="lbox" ItemTemplate="{StaticResource ResourceKey=PasswordViewerTemplate}" ItemsSource="{Binding}"/>
</Grid>
答案 1 :(得分:0)
为什么不在视图模型中绑定项目的可见性?
一个例子。
<Textblock Test="{Binding passwordText,ElementName=This}" Visibility="{Binding passwordTextVisibility}"/>
你的ViewModel中的说
public Visibility passwordTextVisibility
{
getters and setters here
}
并且在您的鼠标事件中,您需要在堆栈面板内部进行某种路由事件。一个例子:
在堆栈面板中你需要鼠标。无论你需要什么。阅读一些关于路由事件的信息实施例。如果PreviewMouseLeftButtonUp
不起作用。
<StackPanel Mouse.MouseUp="MouseButtonUpEventHandler"/>
在视图模型中
public void MouseButtonUpEventHandler (RoutedEvent e)
{
//logic here to check if it's left mouse if it is then set visibility
}
}