コード例 #1
0
        public MainWindow(MainViewModel viewModel)
        {
            // Initialization of a pure WPF command.
            // SimpleWpfCommand is actually a usual "relay" or "delegate" command.
            ResetBindingCommand = new SimpleWpfCommand(OnResetBindingCommand);

            // Initialization of a simple KGy SOFT command. The difference is only the access of these properties from XAML.
            // Instead of the XAML way we could have written: commandBindings.Add(new SimpleCommand(OnWindowClosedCommand)).AddSource(this, "Closed");
            WindowClosedCommand = new SimpleCommand(OnWindowClosedCommand);

            // Similarly, this could have been purely initialized from C# and then we didn't need the public property. See also the examples below.
            AutoGeneratingColumnCommand = new SourceAwareCommand <DataGridAutoGeneratingColumnEventArgs>(OnAutoGeneratingColumnCommand);

            InitializeComponent();
            DataContext    = viewModel;
            this.viewModel = viewModel;

            // And of course we always can use a CommandBindingsCollection instance to create command bindings for any events.
            // This is highly recommended for events of objects that can outlive our window so we can release all of the handlers
            // at once by disposing the CommandBindingsCollection. See also the WindowClosedCommand.

            // Application.Current.DispatcherUnhandledException -> OnCurrentDispatcherUnhandledExceptionCommand
            // Note that we use an implicit command here. It is the shorthand of .Add(new SourceAwareCommand<DispatcherUnhandledExceptionEventArgs>(OnCurrentDispatcherUnhandledExceptionCommand))
            commandBindings.Add <DispatcherUnhandledExceptionEventArgs>(OnCurrentDispatcherUnhandledExceptionCommand)
            .AddSource(Application.Current, nameof(Application.DispatcherUnhandledException));

            // viewModel.PropertyChanged -> OnViewModelPropertyChangedCommand;
            commandBindings.Add <PropertyChangedEventArgs>(OnViewModelPropertyChangedCommand)
            .AddSource(viewModel, nameof(viewModel.PropertyChanged));

            UpdateCurrentView();
        }
コード例 #2
0
        public DebuggerTestForm()
        {
            InitializeComponent();
            cmbPixelFormat.DataSource = viewModel.PixelFormats;

            commandBindings.AddPropertyBinding(chbAsImage, nameof(CheckBox.Checked), nameof(viewModel.AsImage), viewModel);
            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.PixelFormat), nameof(ComboBox.SelectedItem), cmbPixelFormat);
            commandBindings.AddPropertyBinding(cmbPixelFormat, nameof(ComboBox.SelectedValue), nameof(viewModel.PixelFormat), viewModel);

            commandBindings.AddPropertyBinding(rbBitmap, nameof(RadioButton.Checked), nameof(viewModel.Bitmap), viewModel);
            commandBindings.AddPropertyBinding(rbMetafile, nameof(RadioButton.Checked), nameof(viewModel.Metafile), viewModel);
            commandBindings.AddPropertyBinding(rbHIcon, nameof(RadioButton.Checked), nameof(viewModel.HIcon), viewModel);
            commandBindings.AddPropertyBinding(rbManagedIcon, nameof(RadioButton.Checked), nameof(viewModel.ManagedIcon), viewModel);
            commandBindings.AddPropertyBinding(rbGraphicsBitmap, nameof(RadioButton.Checked), nameof(viewModel.GraphicsBitmap), viewModel);
            commandBindings.AddPropertyBinding(rbGraphicsHwnd, nameof(RadioButton.Checked), nameof(viewModel.GraphicsHwnd), viewModel);
            commandBindings.AddPropertyBinding(rbBitmapData, nameof(RadioButton.Checked), nameof(viewModel.BitmapData), viewModel);
            commandBindings.AddPropertyBinding(rbPalette, nameof(RadioButton.Checked), nameof(viewModel.Palette), viewModel);
            commandBindings.AddPropertyBinding(rbColor, nameof(RadioButton.Checked), nameof(viewModel.SingleColor), viewModel);
            commandBindings.AddPropertyBinding(rbFromFile, nameof(RadioButton.Checked), nameof(viewModel.ImageFromFile), viewModel);

            commandBindings.AddPropertyBinding(tbFile, nameof(tbFile.Text), nameof(viewModel.FileName), viewModel);
            commandBindings.AddPropertyBinding(rbAsImage, nameof(RadioButton.Checked), nameof(viewModel.FileAsImage), viewModel);
            commandBindings.AddPropertyBinding(rbAsBitmap, nameof(RadioButton.Checked), nameof(viewModel.FileAsBitmap), viewModel);
            commandBindings.AddPropertyBinding(rbAsMetafile, nameof(RadioButton.Checked), nameof(viewModel.FileAsMetafile), viewModel);
            commandBindings.AddPropertyBinding(rbAsIcon, nameof(RadioButton.Checked), nameof(viewModel.FileAsIcon), viewModel);

            commandBindings.AddPropertyBinding(chbAsReadOnly, nameof(CheckBox.Checked), nameof(viewModel.AsReadOnly), viewModel);

            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.AsImageEnabled), nameof(chbAsImage.Enabled), chbAsImage);
            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.PixelFormatEnabled), nameof(cmbPixelFormat.Enabled), cmbPixelFormat);
            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.ImageFromFile), nameof(gbFile.Enabled), gbFile);
            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.AsReadOnlyEnabled), nameof(chbAsReadOnly.Enabled), chbAsReadOnly);
            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.CanDebug), nameof(Button.Enabled), btnViewDirect, btnViewByDebugger);
            commandBindings.AddPropertyBinding(viewModel, nameof(viewModel.PreviewImage), nameof(pictureBox.Image), pictureBox);

            commandBindings.Add <EventArgs>(OnSelectFileCommand)
            .AddSource(tbFile, nameof(tbFile.Click))
            .AddSource(tbFile, nameof(tbFile.DoubleClick));
            commandBindings.Add(viewModel.DirectViewCommand).AddSource(btnViewDirect, nameof(btnViewDirect.Click));
            commandBindings.Add(viewModel.DebugCommand).AddSource(btnViewByDebugger, nameof(btnViewByDebugger.Click));

            viewModel.GetHwndCallback = () => Handle;
            viewModel.GetClipCallback = () => pictureBox.Bounds;

            // Due to some strange issue on Linux the app crashes if we show a MessageBox while changing radio buttons
            // so as a workaround we show error messages by using a timer. Another solution would be to show a custom dialog.
            timer = new Timer {
                Interval = 1
            };
            viewModel.ErrorCallback = message =>
            {
                errorMessage  = message;
                timer.Enabled = true;
            };
            commandBindings.Add(OnShowErrorCommand)
            .AddSource(timer, nameof(timer.Tick));
        }
コード例 #3
0
        internal static ICommandBinding AddPropertyChangedHandler(this CommandBindingsCollection collection, Action handler, INotifyPropertyChanged source, params string[] propertyNames)
        {
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            if (propertyNames == null)
            {
                throw new ArgumentNullException(nameof(propertyNames));
            }

            var state = new Dictionary <string, object>
            {
                [stateHandler]       = handler,
                [statePropertyNames] = propertyNames
            };

            return(collection.Add(propertyChangedCommand, state)
                   .AddSource(source, nameof(source.PropertyChanged)));
        }
コード例 #4
0
        public MainForm(MainViewModel viewModel)
        {
            InitializeComponent();

            this.viewModel           = viewModel;
            grid.AutoGenerateColumns = true;

            errorProvider.Icon   = Images.Error;
            warningProvider.Icon = Images.Warning;
            infoProvider.Icon    = Images.Information;

            // For the better overview even the standard WinForms bindings are set here instead of the designer.

            // listBindingSource -> grid/listBox/errorProvider/tbIntPropList/tbStringPropList/editMenuStrip
            tbIntPropList.DataBindings.Add(nameof(TextBox.Text), listBindingSource, nameof(ITestObject.IntProp));
            tbStringPropList.DataBindings.Add(nameof(TextBox.Text), listBindingSource, nameof(ITestObject.StringProp));
            editMenuStrip.DataBindings.Add(nameof(editMenuStrip.DataSource), listBindingSource, String.Empty);

            // itemBindingSource -> tbIntPropCurrent/tbStringPropCurrent
            tbIntPropCurrent.DataBindings.Add(nameof(TextBox.Text), itemBindingSource, nameof(ITestObject.IntProp));
            tbStringPropCurrent.DataBindings.Add(nameof(TextBox.Text), itemBindingSource, nameof(ITestObject.StringProp));

            // A ToolStripButton does not support regular WinForms binding. But as it has a CheckedChanged event, KGy SOFT's command binding can be used for it.
            // btnChangeInner.Checked -> viewModel.ChangeUnderlyingCollection - AddPropertyBinding will use an internal command for the change event.
            commandBindings.AddPropertyBinding(btnChangeInner, nameof(btnChangeInner.Checked), nameof(viewModel.ChangeUnderlyingCollection), viewModel);

            // Binding radio buttons by KGy SOFT's command binding, too (regular WinForms binding behaves strangely for radio buttons).
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseList), rbList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseBindingList), rbBindingList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseSortableBindingList), rbSortableBindingList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseSortableBindingListSortOnChange), rbSortableBindingListSortOnChange, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseObservableCollection), rbObservableCollection, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseObservableBindingList), rbObservableBindingList, nameof(RadioButton.Checked));

            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.NoInnerList), rbNoInnerList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.InnerList), rbInnerList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.InnerBindingList), rbInnerBindingList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.InnerSortableBindingList), rbInnerSortableBindingList, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.InnerObservableCollection), rbInnerObservableCollection, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.InnerObservableBindingList), rbInnerObservableBindingList, nameof(RadioButton.Checked));

            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UsePlainTestObject), rbObject, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseObservableTestObject), rbObservableObject, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseUndoableTestObject), rbUndoable, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseEditableTestObject), rbEditable, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseValidatingTestObject), rbValidating, nameof(RadioButton.Checked));
            commandBindings.AddTwoWayPropertyBinding(viewModel, nameof(viewModel.UseAllInOneTestObject), rbModel, nameof(RadioButton.Checked));

            // Binding to ViewModel Commands. Using a shared state for the indexing commands so we can set their Enabled status at once.
            // Adding PropertyCommandStateUpdater.Updater to them so their source buttons will reflect the Enabled state.
            commandsWithCurrentItemState = new CommandState {
                Enabled = false
            };
            commandBindings.Add(viewModel.AddItemCommand, btnAdd, nameof(btnAdd.Click));   // btnAdd.Click -> viewModel.AddItemCommand
            commandBindings.Add(viewModel.RemoveItemCommand, commandsWithCurrentItemState) // btnRemove.Click -> viewModel.RemoveItemCommand
            .WithParameter(() => listBindingSource.Current)
            .AddStateUpdater(PropertyCommandStateUpdater.Updater)
            .AddSource(btnRemove, nameof(btnRemove.Click));
            commandBindings.Add(viewModel.SetItemCommand, commandsWithCurrentItemState) // btnSetItem.Click -> viewModel.SetItemCommand
            .WithParameter(() => listBindingSource.Current)
            .AddStateUpdater(PropertyCommandStateUpdater.Updater)
            .AddSource(btnSetItem, nameof(btnSetItem.Click));
            commandBindings.Add(viewModel.SetItemPropertyCommand, commandsWithCurrentItemState) // btnSetProp.Click -> viewModel.SetItemPropertyCommand
            .WithParameter(() => listBindingSource.Current)
            .AddStateUpdater(PropertyCommandStateUpdater.Updater)
            .AddSource(btnSetProp, nameof(btnSetProp.Click));

            // Note that the following bindings don't reference any explicitly defined ICommands instances. We can do this for private commands not used by anyone else.
            commandBindings.Add <CommandErrorEventArgs>(OnCommandErrorHandler) // viewModel.CommandError -> OnCommandErrorHandler
            .AddSource(viewModel, nameof(viewModel.CommandError));
            commandBindings.Add <EventArgs>(OnRebindCommand)                   // this.Load/viewModel.PropertyChanged -> OnRebindCommand
            .AddSource(this, nameof(Load))
            .AddSource(viewModel, nameof(MainViewModel.PropertyChanged));
            commandBindings.Add(() => { }).AddSource(grid, nameof(grid.DataError));                 // grid.DataError: adding an empty handler so no dialogs will be popped up endlessly on errors
            commandBindings.Add <EventArgs>(OnListBindingSourceCurrentItemChangedCommand)           // listBindingSource.CurrentItemChanged -> OnListBindingSourceCurrentItemChangedCommand
            .AddSource(listBindingSource, nameof(listBindingSource.CurrentItemChanged));
            commandBindings.Add(OnResetBindingCommand).AddSource(btnReset, nameof(btnReset.Click)); // btnReset.Click -> OnResetBindingCommand

            // even static events are supported, provide a type as source:
            commandBindings.Add <ThreadExceptionEventArgs>(OnApplicationThreadExceptionCommand) // Application.ThreadException -> OnApplicationThreadExceptionCommand
            .AddSource(typeof(Application), nameof(Application.ThreadException));
        }