我有一个包含对象集合的ItemsControl。我不希望能够点击对象,然后得到一个面板与更多的信息。
因此,我决定将ItemsControl中项目的DataTemplate样式化为按钮,这似乎可以很好地工作。但是,我不知道如何在样式中设置此按钮的单击事件。它说我应该使用EventSetter,但是我不能让它工作。
代码如下:
<Style TargetType="Expander" >
<Style.Resources>
<Style TargetType="ItemsControl" >
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border BorderThickness="0,1,0,1" BorderBrush="{StaticResource DarkColorBrush}" >
<ScrollViewer Margin="0" VerticalScrollBarVisibility="Auto"
Focusable="false">
<StackPanel Margin="2" IsItemsHost="True" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate" >
<Setter.Value>
<DataTemplate DataType="{x:Type data:CompanyViewModel}" >
<Button>
<Button.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Bd" BorderBrush="{StaticResource DarkColorBrush}"
BorderThickness="1"
Margin="5"
CornerRadius="8">
<Border.Background>
<!-- Removed for brevity -->
</Border.Background>
<StackPanel Orientation="Vertical">
<TextBlock Margin="5" Text="{Binding Path=Name}" Style="{StaticResource MenuText}" FontSize="16" HorizontalAlignment="Center" />
<TextBlock Margin="5,0,5,5" Text="{Binding Path=Code, StringFormat=Kt. {0}}" Style="{StaticResource MenuText}" HorizontalAlignment="Center" />
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Bd" Property="Background">
<Setter.Value>
<!-- Removed for brevity -->
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter TargetName="Bd" Property="Background">
<Setter.Value>
<!-- Removed for brevity -->
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
</Button>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="Expander">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="1"
IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter Name="Content" Grid.Column="0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="Content" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我决定添加我想要通过单击按钮来完成的功能:
<Button Click="CompanyClick" />
在后台代码中定义的CompanyClick。
发布于 2010-07-21 23:32:50
还有这个:
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<!-- Animations manipulating the button here -->
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!-- The rest of your triggers here -->
</ControlTemplate.Triggers>
模板中的这种机制将使您能够控制按钮的属性,并可能控制可视化树的其他部分中的属性,这取决于您将定义放在哪里。
您可能还会考虑以不同的方式设计一些东西。我不一定会以完全相同的方式将所有的定义堆积到样式中。
发布于 2010-07-19 23:44:49
变化
<Button>
为了..。
<Button Command="{Binding OnClick}" />
在用作此ItemsControl中的项的类上,实现一个只读属性,该属性为要使用的按钮返回一个ICommand。
编辑:
在本例中,我使用了一个名为RelayCommand
的ICommand实现,它可以在http://msdn.microsoft.com/en-us/magazine/dd419663.aspx上找到。有关C#中的完整RelayCommand
类,请参阅该文章的图3。我将其转换为Visual Basic供我使用,代码如下。它所做的仅仅是在WPF系统中自动注册命令,并为您提供一个方便的构造函数:
''' <summary>
''' Implements the ICommand interface
''' </summary>
''' <remarks>
''' Thanks to Josh Smith for this code: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
''' </remarks>
Public Class RelayCommand
Implements ICommand
#Region "Fields"
Private ReadOnly _execute As Action(Of Object)
Private ReadOnly _canExecute As Predicate(Of Object)
#End Region ' Fields
#Region "Constructors"
Public Sub New(ByVal execute As Action(Of Object))
Me.New(execute, Nothing)
End Sub
Public Sub New(ByVal execute As Action(Of Object), ByVal canExecute As Predicate(Of Object))
If execute Is Nothing Then
Throw New ArgumentNullException("execute")
End If
_execute = execute
_canExecute = canExecute
End Sub
#End Region ' Constructors
#Region "ICommand Members"
<DebuggerStepThrough()>
Public Function CanExecute(ByVal parameter As Object) As Boolean Implements ICommand.CanExecute
Return If(_canExecute Is Nothing, True, _canExecute(parameter))
End Function
Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
AddHandler(ByVal value As EventHandler)
AddHandler CommandManager.RequerySuggested, value
End AddHandler
RemoveHandler(ByVal value As EventHandler)
RemoveHandler CommandManager.RequerySuggested, value
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
CommandManager.InvalidateRequerySuggested()
End RaiseEvent
End Event
Public Sub Execute(ByVal parameter As Object) Implements ICommand.Execute
_execute(parameter)
End Sub
#End Region ' ICommand Members
End Class
使用该类,您可以在ViewModel上实现ICommand
,方法是在该类中将ICommand
公开为只读属性,并提供一个用于存储RelayCommand的后备字段,别忘了,该字段实现了ICommand。下面是一个截断的示例:
Public Class CompanyViewModel
Implements INotifyPropertyChanged
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Private _OnClick As RelayCommand
Public ReadOnly Property OnClick As ICommand
Get
If _OnClick Is Nothing Then
_OnClick = New RelayCommand(Sub()
Me.OnClickExecute()
End Sub,
Function()
Return Me.OnClickCanExecute()
End Function)
End If
Return _OnClick
End Get
End Property
Private Function OnClickCanExecute() As Boolean
' put a test here to tell the system whether conditions are right to execute your command.
' OR, just return True and it will always execute the command.
End Function
Private Sub OnClickExecute()
' put the processing for your command here; THIS IS YOUR EVENT HANDLER
End Sub
' .... implement the rest of your ViewModel
End Class
"OnClick“名称不是必需的;命令可以采用任何名称,因为系统不像VB6处理其事件处理程序那样是基于约定的。
有不止一种方法可以做到这一点。我对ICommand的"Caliburn.Micro“实现很感兴趣,它是基于约定的,根据您的风格,它可能会使内容更具可读性。但是,Caliburn是一个爱好者的开源努力,尽管他是一个非常有能力和合格的爱好者。谷歌或必应搜索"Caliburn.Micro“获取更多信息。
https://stackoverflow.com/questions/3282441
复制相似问题