基本信息
源码名称:C# 实现可编辑的listview 示例(wpf)
源码大小:0.10M
文件格式:.zip
开发语言:C#
更新时间:2019-04-05
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):78630559

本次赞助数额为: 2 元 
   源码介绍

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows;
using System.Diagnostics;
using System.Windows.Documents;
using System.Windows.Media;

namespace Editing
{
    /// <summary>
    /// EditBox is a custom cotrol that can switch between two modes: 
    /// editing and normal. When it is in editing mode, the content is
    /// displayed in a TextBox that provides editing capbability. When 
    /// the EditBox is in normal, its content is displayed in a TextBlock
    /// that is not editable.
    /// 
    /// This control is designed to be used in with a GridView View.
    /// </summary>
    // <!--<SnippetEditBoxStart>
    public class EditBox : Control
    {
    // <!--</SnippetEditBoxStart>

        #region Static Constructor

        /// <summary>
        /// Static constructor
        /// </summary>
        static EditBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(EditBox), 
                new FrameworkPropertyMetadata(typeof(EditBox)));
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Called when the tree for the EditBox has been generated.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            TextBlock textBlock = GetTemplateChild("PART_TextBlockPart") 
                   as TextBlock;
            Debug.Assert(textBlock != null, "No TextBlock!");

            _textBox = new TextBox();
            _adorner = new EditBoxAdorner(textBlock, _textBox,this.Width);
            AdornerLayer layer = AdornerLayer.GetAdornerLayer(textBlock);
            layer.Add(_adorner);

            _textBox.KeyDown  = new KeyEventHandler(OnTextBoxKeyDown);
            _textBox.LostKeyboardFocus  = 
              new KeyboardFocusChangedEventHandler(OnTextBoxLostKeyboardFocus);
            _textBox.Focus();
            //Receive notification of the event to handle the column 
            //resize. 
            HookTemplateParentResizeEvent();

            //Capture the resize event to  handle ListView resize cases.
            HookItemsControlEvents();

            _listViewItem = GetDependencyObjectFromVisualTree(this, 
                typeof(ListViewItem)) as ListViewItem;

            Debug.Assert(_listViewItem != null, "No ListViewItem found");
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// If the ListViewItem that contains the EditBox is selected, 
        /// when the mouse pointer moves over the EditBox, the corresponding
        /// MouseEnter event is the first of two events (MouseUp is the second)
        /// that allow the EditBox to change to editing mode.
        /// </summary>
        //<SnippetOnMouseEnter>
        protected override void OnMouseEnter(MouseEventArgs e)
        {
            base.OnMouseEnter(e);
            if (!IsEditing && IsParentSelected)
            {
                _canBeEdit = true;
            }
        }
        //</SnippetOnMouseEnter>

        /// <summary>
        /// If the MouseLeave event occurs for an EditBox control that
        /// is in normal mode, the mode cannot be changed to editing mode
        /// until a MouseEnter event followed by a MouseUp event occurs.
        /// </summary>
        //<SnippetOnMouseLeave>
        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);
            _isMouseWithinScope = false;
            _canBeEdit = false;
        }
        //</SnippetOnMouseLeave>
        /// <summary>
        /// An EditBox switches to editing mode when the MouseUp event occurs
        /// for that EditBox and the following conditions are satisfied:
        /// 1. A MouseEnter event for the EditBox occurred before the 
        /// MouseUp event.
        /// 2. The mouse did not leave the EditBox between the
        /// MouseEnter and MouseUp events.
        /// 3. The ListViewItem that contains the EditBox was selected
        /// when the MouseEnter event occurred.
        /// </summary>
        /// <param name="e"></param>
        //<SnippetOnMouseUp>
        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            base.OnMouseUp(e);
            if (e.ChangedButton == MouseButton.Right || 
                e.ChangedButton == MouseButton.Middle)
                return;

            if (!IsEditing)
            {
                if (!e.Handled && (_canBeEdit || _isMouseWithinScope))
                {
                    IsEditing = true;
                }

                //If the first MouseUp event selects the parent ListViewItem,
                //then the second MouseUp event puts the EditBox in editing 
                //mode
                if (IsParentSelected)
                    _isMouseWithinScope = true;
            }
        }
        //</SnippetOnMouseUp>

        #endregion

        #region Public Properties

        #region Value

        /// <summary>
        /// ValueProperty DependencyProperty.
        /// </summary>
        //<SnippetValueProperty>
        public static readonly DependencyProperty ValueProperty =
                DependencyProperty.Register(
                        "Value",
                        typeof(object),
                        typeof(EditBox),
                        new FrameworkPropertyMetadata(null));
        //</SnippetValueProperty>

        /// <summary>
        /// Gets or sets the value of the EditBox
        /// </summary>
         public object Value
        {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        #endregion

        #region IsEditing

        /// <summary>
        /// IsEditingProperty DependencyProperty
        /// </summary>
        //<SnippetIsEditingProperty>
        public static DependencyProperty IsEditingProperty =
                DependencyProperty.Register(
                        "IsEditing",
                        typeof(bool),
                        typeof(EditBox),
                        new FrameworkPropertyMetadata(false));
        //</SnippetIsEditingProperty>

        /// <summary>
        /// Returns true if the EditBox control is in editing mode.
        /// </summary>
        public bool IsEditing
        {
            get { return (bool)GetValue(IsEditingProperty); }
            private set
            {
                if (value)
                    _useEditMessageChanged = true;
                else if (_useEditMessageChanged && EditMessageChanged != null)
                {
                    _useEditMessageChanged = false;
                    EditMessageChanged();
                }
                SetValue(IsEditingProperty, value);
                _adorner.UpdateVisibilty(value);
            }
        }

        #endregion

        #region IsParentSelected

        /// <summary>
        /// Gets whether the ListViewItem that contains the 
        /// EditBox is selected.
        /// </summary>
        private bool IsParentSelected
        {
            get
            {
                if (_listViewItem == null)
                    return false;
                else
                    return _listViewItem.IsSelected;
            }
        }

        #endregion

        #endregion

        #region Private Methods

        /// <summary>
        /// When an EditBox is in editing mode, pressing the ENTER or F2
        /// keys switches the EditBox to normal mode.
        /// </summary>
        private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
        {
            if (IsEditing && (e.Key == Key.Enter || e.Key == Key.F2))
            {
                IsEditing = false;
                _canBeEdit = false;
            }
        }

        /// <summary>f
        /// If an EditBox loses focus while it is in editing mode, 
        /// the EditBox mode switches to normal mode.
        /// </summary>
        private void OnTextBoxLostKeyboardFocus(object sender, 
                                             KeyboardFocusChangedEventArgs e)
        {
            if (IsEditing)
                IsEditing = false;
        }

        /// <summary>
        /// Sets IsEditing to false when the ListViewItem that contains an
        /// EditBox changes its size
        /// </summary>
        private void OnCouldSwitchToNormalMode(object sender, 
                                               RoutedEventArgs e)
        {
            if (IsEditing)
                IsEditing = false;
        }

        /// <summary>
        /// Walk the visual tree to find the ItemsControl and 
        /// hook its some events on it.
        /// </summar
        private void HookItemsControlEvents()
        {
            _itemsControl = GetDependencyObjectFromVisualTree(this, 
                                typeof(ItemsControl)) as ItemsControl;
            if (_itemsControl != null)
            {
                //Handle the Resize/ScrollChange/MouseWheel 
                //events to determine whether to switch to Normal mode
                _itemsControl.SizeChanged  = 
                    new SizeChangedEventHandler(OnCouldSwitchToNormalMode);
                _itemsControl.AddHandler(ScrollViewer.ScrollChangedEvent, 
                    new RoutedEventHandler(OnScrollViewerChanged));
                _itemsControl.AddHandler(ScrollViewer.MouseWheelEvent, 
                    new RoutedEventHandler(OnCouldSwitchToNormalMode), true);
            }
        }

        /// <summary>
        /// If an EditBox is in editing mode and the content of a ListView is
        /// scrolled, then the EditBox switches to normal mode.
        /// </summary>
        private void OnScrollViewerChanged(object sender, RoutedEventArgs args)
        {
            if (IsEditing && Mouse.PrimaryDevice.LeftButton == 
                                MouseButtonState.Pressed)
            {
                IsEditing = false;
            }
        }

        /// <summary>
        /// Walk visual tree to find the first DependencyObject 
        /// of the specific type.
        /// </summary>
        private DependencyObject 
            GetDependencyObjectFromVisualTree(DependencyObject startObject, 
                                              Type type)
        {
            //Walk the visual tree to get the parent(ItemsControl) 
            //of this control
            DependencyObject parent = startObject;
            while (parent != null)
            {
                if (type.IsInstanceOfType(parent))
                    break;
                else
                    parent = VisualTreeHelper.GetParent(parent);
            }

            return parent;
        }

        /// <summary>
        /// When the size of the column containing the EditBox changes
        /// and the EditBox is in editing mode, switch the mode to normal mode 
        /// </summary>
        private void HookTemplateParentResizeEvent()
        {
            FrameworkElement parent = TemplatedParent as FrameworkElement;
            if (parent != null)
            {
                parent.SizeChanged  = 
                    new SizeChangedEventHandler(OnCouldSwitchToNormalMode);
            }
        }

        #endregion

        #region private variable
        
        private EditBoxAdorner _adorner; 
        //A TextBox in the visual tree
        private FrameworkElement _textBox;
        //Specifies whether an EditBox can switch to editing mode. 
        //Set to true if the ListViewItem that contains the EditBox is 
        //selected, when the mouse pointer moves over the EditBox
        private bool _canBeEdit = false;
        //Specifies whether an EditBox can switch to editing mode.
        //Set to true when the ListViewItem that contains the EditBox is 
        //selected when the mouse pointer moves over the EditBox.
        private bool _isMouseWithinScope = false;
        //The ListView control that contains the EditBox
        private ItemsControl _itemsControl;
        //The ListViewItem control that contains the EditBox
        private ListViewItem _listViewItem;
        //是否可使用信息修改事件
        private bool _useEditMessageChanged = false;
        //edit信息修改事件
        public delegate void _EditMessageChanged();
        //声明一个事件
        public event _EditMessageChanged EditMessageChanged;

        #endregion
   //<SnippetEditBoxEnd>
    }
   //</SnippetEditBoxEnd>

}