Wpf DataTemplate事件处理程序

时间:2016-02-14 06:17:47

标签: c# wpf xaml events datatemplate

我扩展了ListView类,并在单独的Resource文件中为它创建了两个server { listen 80; server_name domain.com.localhost www.domain.com.localhost; access_log /usr/local/var/log/nginx/domain.com.access.log; location /robots.txt { alias /Users/user/Sites/domain.com/app/robots.txt; } location ~ ^/(images/|javascripts/|stylesheets/|fonts) { root /Users/user/Sites/domain.com/app/assets; access_log off; expires max; } location / { set $fixed_destination $http_destination; if ( $http_destination ~* ^https(.*)$ ) { set $fixed_destination http$1; } proxy_pass http://127.00.0.1:8002/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Destination $fixed_destination; client_max_body_size 32M; client_body_buffer_size 512k; proxy_connect_timeout 300; proxy_send_timeout 300; proxy_read_timeout 300; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } } 。我的问题是我如何为DataTemplate中的Checkbox(以及其他项目)添加事件处理程序?

MyListView.cs

DataTemplate

MyListViewItem.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfCustomControlLibrary1
{
    public class MyListView : ListView
    {
        public enum ListMode
        {
            List, ListCheck
        }

        public static readonly DependencyProperty ModeProperty = DependencyProperty.Register
        (
            "Mode",
            typeof(ListMode),
            typeof(MyListView),
            new PropertyMetadata(ListMode.List)
        );

        public ListMode Mode
        {
            get { return (ListMode)GetValue(ModeProperty); }
            set { SetValue(ModeProperty, value); }
        }
    }
}

ResourceDictionary.xaml

using System.Windows;
using System.Windows.Controls;

namespace WpfCustomControlLibrary1
{
    public class MyListViewItem:Control
    {
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register
        (
            "Text",
            typeof(string),
            typeof(MyListViewItem),
            new UIPropertyMetadata(string.Empty)
        );

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register
        (
            "IsChecked",
            typeof(bool),
            typeof(MyListViewItem),
            new UIPropertyMetadata(false)
        );

        public bool IsChecked
        {
            get { return (bool)GetValue(IsCheckedProperty); }
            set { SetValue(IsCheckedProperty, value); }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您的问题涉及Event handlers及其在资源文件中的使用。无法直接在资源文件中存储的XAML中表达对代码隐藏的访问。

虽然您可以在UserControl的XAML中执行以下操作,但

    <CheckBox Click="CheckBox_OnClick"/>

在单独的资源目录中分离样式时,这是不可能的。

这是ICommand接口通常在ViewModel上触发,但也可用于触发代码隐藏的地方。然后语法变为(如果您希望触发代码隐藏): -

   <CheckBox Command="{Binding CheckBoxClickedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType='MyListView'}}"/>

如果您: -

,这将允许您在MyListView课程中触发代码
  1. 向您的CheckBoxClickedCommand班级
  2. 添加名为MyListView的媒体资源
  3. 在该类的属性
  4. 上添加ICommand的支持界面

    通常使用RelayCommand实现,因此您可以提供Lambda表达式来简化实现。快速搜索RelayCommand会为您提供一些指导。

    这一切听起来都不错,直到您发现只有某些控件(例如ButtonCheckboxRadioButton)将Command模式作为标准实现。

    幸运的是,自Blend 3以来,我们现在有更多的空间使用行为使用ICommand模式,这也是您可能想要研究的内容。

      <CheckBox Command="{Binding CheckBoxClickedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <i:InvokeCommandAction Command="{Binding CheckBoxMouseEnterCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Checkbox>
    

    此处可以使用MouseEnter等其他事件来发起ICommand来电。这也意味着其他不支持Command=属性的控件也可以调用代码隐藏。