コード例 #1
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));
        }