使用MVVM在WPF中监视背景剪贴板并在View中绑定复制的上下文

时间:2016-08-26 21:31:46

标签: c# wpf mvvm

我一直在尝试制作WPF Windows程序(C#)。在UI中,我一直在计划将有一个文本列表,显示用户在程序打开时复制了什么。因此程序收集复制的字符串并将其显示在窗口的列表中。

我的问题是我想要这样做MVVM,我对它并不熟悉。 我试图监控用户剪贴板更改的方式是这样的: https://stackoverflow.com/a/33018459/6741346。 我不知道是否有更容易或更好的MVVM版本来监控剪贴板的变化?

问题是我不确定应该如何制作视图模型。我知道我需要ObservableCollection并将其绑定到View。但我不知道我怎么能这样做,当用户更改剪贴板时,它会更新Observablecollection,然后自动显示对Window的listview的更改。

2 个答案:

答案 0 :(得分:2)

对于MVVM,您可以从我的ClipboardMonitorWindow类派生主窗口并注册剪贴板更新命令。它没有表格就完整了。

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;

public class ClipboardMonitorWindow : Window
{
    private const int WM_CLIPBOARDUPDATE = 0x031D;

    private IntPtr windowHandle;

    public event EventHandler ClipboardUpdate;

    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);

        windowHandle = new WindowInteropHelper(this).EnsureHandle();
        HwndSource.FromHwnd(windowHandle)?.AddHook(HwndHandler);
        Start();
    }

    public static readonly DependencyProperty ClipboardUpdateCommandProperty =
        DependencyProperty.Register("ClipboardUpdateCommand", typeof(ICommand), typeof(ClipboardMonitorWindow), new FrameworkPropertyMetadata(null));

    public ICommand ClipboardUpdateCommand
    {
        get { return (ICommand)GetValue(ClipboardUpdateCommandProperty); }
        set { SetValue(ClipboardUpdateCommandProperty, value); }
    }

    protected virtual void OnClipboardUpdate()
    { }

    public void Start()
    {
        NativeMethods.AddClipboardFormatListener(windowHandle);
    }

    public void Stop()
    {
        NativeMethods.RemoveClipboardFormatListener(windowHandle);
    }

    private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    {
        if (msg == WM_CLIPBOARDUPDATE)
        {
            // fire event
            this.ClipboardUpdate?.Invoke(this, new EventArgs());
            // execute command
            if (this.ClipboardUpdateCommand?.CanExecute(null) ?? false)
            {
                this.ClipboardUpdateCommand?.Execute(null);
            }
            // call virtual method
            OnClipboardUpdate();
        }
        handled = false;
        return IntPtr.Zero;
    }


    private static class NativeMethods
    {
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool AddClipboardFormatListener(IntPtr hwnd);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
    }
}

答案 1 :(得分:0)

根据您希望应用程序的工作方式,您可能不需要1940 .. current year + 2 years

如果您只是想在剪贴板中查看最新内容,那么实现INPC的简单模型就足够了。但是,如果您要查看剪贴板更改的历史记录,则需要// search template from http://stackoverflow.com/questions/8710162/jqgrid-calendar-icon-not-showing-up-in-inline-editing-mode var DateTemplate = { sorttype: 'date', formatter: 'date', formatoptions: { srcformat: "Y-m-d", //added according to http://www.trirand.com/blog/?page_id=393/bugs/date-problem reformatAfterEdit: true }, editoptions: { maxlength: 10, size: 10, dataInit: initDateEdit }, editable: true, searchoptions: { clearSearch: false, / // for the searching toolbar: // http://stackoverflow.com/questions/34475094/how-to-make-html5-date-field-in-search-toolbar-to-respect-column-width attr: { size: 10, type: "date", style: "width:11em;" }, sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'], dataInit: initDateHtmlSearch, size: 11 // for the advanced searching dialog } }; // http://stackoverflow.com/questions/29194381/how-to-use-native-datapicker-in-both-form-and-row-editing-in-free-jqgrid // http://stackoverflow.com/questions/26040738/how-to-use-input-type-date-for-date-column-in-jqgrid var initDateEdit = function (elem, options) { // we need get the value before changing the type var orgValue = $(elem).val(), newformat, cm = $(this).jqGrid("getColProp", options.name); $(elem).attr("type", "date"); if ((typeof Modernizr !== "undefined" && !Modernizr.inputtypes.date) || $(elem).prop("type") !== "date") { $(elem).attr("type", "text"); // !!! important to make saving works correctly $(elem).css({ width: "8em" }).datepicker({ autoSize: true, changeYear: true, changeMonth: true, showButtonPanel: true, showWeek: true }); } else { // convert date to ISO if (orgValue !== "") { newformat = cm.formatoptions !== null && cm.formatoptions.newformat ? cm.formatoptions.newformat : $(this).jqGrid("getGridRes", "formatter.date.newformat"); $(elem).val($.jgrid.parseDate.call(this, newformat, orgValue, "Y-m-d")); } $(elem).css({ width: "10em" }); } }; 。要更新它,只需向ObservableCollection添加处理程序,并确保使用ObservableCollection从UI线程更新ClipboardManager.ClipboardChanged