Wpf 在元素之间的用户控件内触发事件
Wpf trigging events inside user control between elements
我有一个具有两个网格的 ListViewItem。当用户单击第一个网格时,它会显示第二个网格。但由于它是一个用户控件,我无法在代码隐藏中找到它。
<UserControl>
<ListView>
<ListView.ItemTemplate>
<DataTemplate DataType="models:Tweet">
<ListViewItem>
<Grid Name="Grid1" OnMouseLeftDown="ShowsGrid2"/>
<Grid Name="Grid2"/>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource {x:Type ListViewItem}}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</UserControl>
public void PreviewMouseLeftButtonDown(object sender)
{
var control = (Grid)sender;
sender.Visibility = Visibility.Visible;
}
但我得到:control = null Exception
我建议在您的代码隐藏中创建一个 属性:
public Visibility Grid2Visibility { get; set; }
然后,将网格的可见性绑定到 属性,在 XAML:
<Grid ... Visibility="{Binding Grid2Visibility}" ... />
然后,您可以处理任何您想要的事件并相应地设置 Grid2 的可见性:
public void HandleSomeEvent(object sender, SomeArgs e)
{
// I can collapse Grid2
Grid2Visibility = Visibility.Collapsed;
// or I can show it
Grid2Visibility = Visibility.Visible;
}
另一种选择是使用 Triggers。下面是一个按钮的点击事件触发第二个按钮可见性的简单示例:
<StackPanel>
<Button Content="Button 1">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.Target="{x:Reference Button2}" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Name="Button2" Visibility="Collapsed">Button 2</Button>
</StackPanel>
下面是一个简单的示例,说明如何执行隐藏代码。
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Visibility _gird2Visibility;
public Visibility Grid2Visibility
{
get { return _gird2Visibility; }
set
{
_gird2Visibility = value;
OnPropertyChanged("Grid2Visibility");
}
}
public MainWindow()
{
InitializeComponent();
Grid2Visibility = Visibility.Hidden;
}
private void Grid1_OnMouseDown(object sender, MouseButtonEventArgs e)
{
Grid2Visibility = Visibility.Visible;
}
private void Grid1_OnMouseUp(object sender, MouseButtonEventArgs e)
{
Grid2Visibility = Visibility.Hidden;
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
这是XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Name="Grid1" MouseDown="Grid1_OnMouseDown" MouseUp="Grid1_OnMouseUp" >
<TextBlock Text="CLICK ANYWHERE WITHIN THE GRID TO SHOW SECOND GRID" />
</Grid>
<Grid Grid.Row="1" Name="Grid2" Visibility="{Binding Grid2Visibility}" >
<TextBlock Text="I AM VISIBLE" />
</Grid>
</Grid>
我不知道您 window 的数据上下文。然而,这就是我在我的示例中设置它的方式
DataContext="{Binding RelativeSource={RelativeSource Self}}"
我有一个具有两个网格的 ListViewItem。当用户单击第一个网格时,它会显示第二个网格。但由于它是一个用户控件,我无法在代码隐藏中找到它。
<UserControl>
<ListView>
<ListView.ItemTemplate>
<DataTemplate DataType="models:Tweet">
<ListViewItem>
<Grid Name="Grid1" OnMouseLeftDown="ShowsGrid2"/>
<Grid Name="Grid2"/>
</ListViewItem>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource {x:Type ListViewItem}}">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListViewItem_PreviewMouseLeftButtonDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
</UserControl>
public void PreviewMouseLeftButtonDown(object sender)
{
var control = (Grid)sender;
sender.Visibility = Visibility.Visible;
}
但我得到:control = null Exception
我建议在您的代码隐藏中创建一个 属性:
public Visibility Grid2Visibility { get; set; }
然后,将网格的可见性绑定到 属性,在 XAML:
<Grid ... Visibility="{Binding Grid2Visibility}" ... />
然后,您可以处理任何您想要的事件并相应地设置 Grid2 的可见性:
public void HandleSomeEvent(object sender, SomeArgs e)
{
// I can collapse Grid2
Grid2Visibility = Visibility.Collapsed;
// or I can show it
Grid2Visibility = Visibility.Visible;
}
另一种选择是使用 Triggers。下面是一个按钮的点击事件触发第二个按钮可见性的简单示例:
<StackPanel>
<Button Content="Button 1">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.Target="{x:Reference Button2}" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Button Name="Button2" Visibility="Collapsed">Button 2</Button>
</StackPanel>
下面是一个简单的示例,说明如何执行隐藏代码。
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Visibility _gird2Visibility;
public Visibility Grid2Visibility
{
get { return _gird2Visibility; }
set
{
_gird2Visibility = value;
OnPropertyChanged("Grid2Visibility");
}
}
public MainWindow()
{
InitializeComponent();
Grid2Visibility = Visibility.Hidden;
}
private void Grid1_OnMouseDown(object sender, MouseButtonEventArgs e)
{
Grid2Visibility = Visibility.Visible;
}
private void Grid1_OnMouseUp(object sender, MouseButtonEventArgs e)
{
Grid2Visibility = Visibility.Hidden;
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
这是XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Name="Grid1" MouseDown="Grid1_OnMouseDown" MouseUp="Grid1_OnMouseUp" >
<TextBlock Text="CLICK ANYWHERE WITHIN THE GRID TO SHOW SECOND GRID" />
</Grid>
<Grid Grid.Row="1" Name="Grid2" Visibility="{Binding Grid2Visibility}" >
<TextBlock Text="I AM VISIBLE" />
</Grid>
</Grid>
我不知道您 window 的数据上下文。然而,这就是我在我的示例中设置它的方式
DataContext="{Binding RelativeSource={RelativeSource Self}}"