none
Menüpunkte des Mainmenüs (Mainwindow) aus einem Childwindow enable/disable

    Frage

  • Hallo Experten,

    Ich habe in einem Childwindow eine Selectionsfunktion die entweder den gesamten Datenbestand oder nur eine Aussenstelle selektiert. Wenn der Gesamtbestand selektiert wird, sollen einige Menüpunkte des Mainmenues disabled werden, wird dann wieder eine Aussenstelle selektiert sollen wieder alle Menüpunkte auswählbar werden.

    Die Caption des Mainwindows kann ich über this.Parent.Text ändern. Ich bräuchte noch die Möglichkeit auf das Menü des Parentwindow (Mainwindow) zuzugreifen und MenuItems zu en-/disablen.

    Vielen Dank im Voraus

    Siegfried

    Mittwoch, 6. Dezember 2017 14:35

Alle Antworten

  • Hi Siegfried,
    man kann eine Klasse mit einer Eigenschaft erstellen, die zu Zustand verwaltet. Beide Fenster nutzen die gleiche Instanz und nutzen damit die gleichen Eigenschaftswerte. Hier mal eine Demo:

    XAML:

    <Window x:Class="WpfApp1CS.Window27"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window27" Height="300" Width="300">
      <Window.Resources>
        <local:Window27VM x:Key="vm"/>
        <local:Window27Conv x:Key="conv"/>
      </Window.Resources>
      <Grid DataContext="{StaticResource vm}">
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Menu>
          <Button Content="Child" Command="{Binding Cmd}" CommandParameter="Child"/>
          <Button Content="Menü 1" Command="{Binding Cmd}" CommandParameter="Menu1"/>
          <Button Content="Menü 2" Command="{Binding Cmd}" CommandParameter="Menu2"/>
          <Button Content="Menü 3" Command="{Binding Cmd}" CommandParameter="Menu3" 
                  Visibility="{Binding Zustand, Converter={StaticResource conv}}"/>
          <Button Content="Menü 4" Command="{Binding Cmd}" CommandParameter="Menu4"
                  Visibility="{Binding Zustand, Converter={StaticResource conv},ConverterParameter=False}"/>
        </Menu>
        <StackPanel Grid.Row="1">
          <Label Content="Anzeige 1" Margin="10"
                 Visibility="{Binding Zustand, Converter={StaticResource conv},ConverterParameter=False}"/>
          <Label Content="Anzeige 2" Margin="5"
                   Visibility="{Binding Zustand, Converter={StaticResource conv}}"/>
          <Label Content="Anzeige 3"/>
        </StackPanel>
      </Grid>
    </Window>

    Dazu der ViewModel und Konverter:

    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    
    namespace WpfApp1
    {
      public partial class Window27VM : INotifyPropertyChanged
      {
        private bool _zustand = false;
        public bool Zustand
        {
          get { return this._zustand; }
          set { this._zustand = value; OnPropertyChanged(); OnPropertyChanged(nameof(Cmd)); }
        }
    
        public ICommand Cmd { get { return new RelayCommand(CmdExec, CmdCanExec); } }
    
        private void CmdExec(object obj)
        {
          switch (obj.ToString())
          {
            case "Child":
              Window wnd = new Window() { DataContext = this, Width = 100, Height = 100 };
              CheckBox cb = new CheckBox() { Content = "Einstellen" };
              cb.SetBinding(CheckBox.IsCheckedProperty, new Binding("Zustand"));
              wnd.Content = cb;
              wnd.ShowDialog();
              break;
            default:
              break;
          }
        }
        private bool CmdCanExec(object obj)
        {
          switch (obj.ToString())
          {
            case "Menu1": return Zustand;
            case "Menu2": return !Zustand;
            default: return true;
          }
        }
        #region  OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propName = "") =>
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion
    
      }
      public partial class Window27Conv : IValueConverter
      {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
          // Boolean in Visibility, True=sichtbar, wenn Parameter="False", dann true=unsichtbar
          if (value.GetType() == typeof(bool) && targetType == typeof(Visibility))
            if (parameter?.ToString() == "False") return ((bool)value) ? Visibility.Collapsed : Visibility.Visible;
            else return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
          return null;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
          throw new NotImplementedException();
      }
    }


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort vorgeschlagen Peter Fleischer Mittwoch, 6. Dezember 2017 21:41
    Mittwoch, 6. Dezember 2017 19:23
  • Hi Peter,

    vielen Dank für Dein ausführliches Beispiel, ich kann es erst am Wochenende versuchen. Allerdings ist mein Programm eine Forms Anwendung und ich hoffe ich kann das umsetzen.

    Vielen Dank nochmals und viele Grüße

    Siegfried

    Donnerstag, 7. Dezember 2017 12:29
  • Hi Siegfried,
    da Du den Begriff Mainwindow genutzt hast, der im WPF üblich ist, bin ich davon ausgegangen, Dass Du eine WPF Anwendung schreibst.


    Hier mal eine Windows Forms Demo:

    using System;
    using System.Windows.Forms;
    
    namespace WindowsFormsApp1
    {
      public partial class Form15 : Form
      {
        public Form15()
        {
          InitializeComponent();
        }
    
        private Button btn1 = new Button() { Text = "Show Dialog Form", Dock = DockStyle.Top };
        private Button btn2 = new Button() { Text = "Button 2", Dock = DockStyle.Top };
        private Button btn3 = new Button() { Text = "Button 3", Dock = DockStyle.Top };
    
        Form15VM vm = new Form15VM();
    
        private void Form15_Load(object sender, EventArgs e)
        {
          this.Controls.AddRange(new Control[] { btn3, btn2, btn1 });
          btn2.DataBindings.Add("Enabled", vm, "Zustand");
          btn3.DataBindings.Add("Enabled", vm, "ZustandNot");
          btn1.Click += Btn1_Click;
        }
    
        private void Btn1_Click(object sender, EventArgs e)
        {
          Form frm2 = new Form();
          CheckBox cb = new CheckBox() { Text = "Einstellen" };
          cb.DataBindings.Add(new Binding("Checked", vm, "Zustand", false, DataSourceUpdateMode.OnPropertyChanged));
          frm2.Controls.Add(cb);
          frm2.ShowDialog();
        }
      }
    
      public class Form15VM
      {
        private bool _zustand = false;
        public bool Zustand { get { return this._zustand; } set { this._zustand = value; } }
        public bool ZustandNot { get { return !this._zustand; } }
      }
    }

    --

    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks


    Donnerstag, 7. Dezember 2017 14:27