Sorry für die nichtssagende Überschrift, aber ich weiß schlichtweg nicht wie das heißt has ich suche, daher muss ich hier leider etwas ausholen:
In meiner Anwendung gibt es mehrere Formulare welche meistens nach dem selben Schema aufgebaut sind: Für jeden Wert den der Nutzer bearbeiten kann gibt es ein Label mit einer Überschrift und eine TextBox (oder Ähnlich) um den eigentlichen Wert zu ändern.
Die neue Anfoderung ist es nun das der Nutzer die Möglichkeit bekommen soll einzelne Werte ausblenden zu können (nicht jeder Kunde benutzt alle Felder).
Um dieses Problem felxibel zu lösen würde ich gerne ein Behavior verwenden welches ich an alle Controls hängen kann die ausgeblendet werden sollen. Dieses Behavior besteht hauptsächlich aus zwei Properties: Einen Gruppennamen der bei allen Controls gleich ist welche zusammen gehören (also z.B. ein Label mit der Überschrift + die zugehörige Textbox). Außerdem ein Dictionary welches für alle Gruppennamen eines Formulars einen bool-Wert bereit hält welcher die Sichtbarkeit steuern soll.
Innherhalb des Behaviors wird für jedes Control ein ContextMenü angelegt mit dem man eine Übersicht aller Gruppen bekommt und mit dem man einzelne Gruppen an- und abwählen, also sichtbar und unsichtbar machen kann.
Das Ganze funktioniert auch inzwischen bis zu dem Punkt an dem der Benutzer im Kontextmenü eine Gruppe an- oder abwählt. An dieser Stelle müssen nun eigentlich alle Controls getriggert werden so dass sie das Dictionary mit den Gruppennamen nochmals prüfen ob sich ihr Zustand geändert hat. Ich suche also sowas wie einen Event konnte aber im Netz nicht herausfinden wie sowas auszusehen hat. Im Prinzip würde mir reichen wenn mir jemand ein gutes Stichwort gibt oder ein passendes Tutorial verweist.
Hier noch der Code meines Behavior mit einem TODO an der entsprechenden Stelle:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
namespace CustomizableUserControlVisibility
{
public class WPFCustomVisibilityBehavior : Behavior<DependencyObject>
{
#region Fields
private Control _control = null;
private ContextMenu _contextMenu;
private bool _contextMenuIsBuilt = false;
#endregion
#region Properties
public bool AllowCustomVisibility
{
get { return (bool)GetValue(AllowCustomVisibilityProperty); }
set { SetValue(AllowCustomVisibilityProperty, value); }
}
public static readonly DependencyProperty AllowCustomVisibilityProperty = DependencyProperty.Register("AllowCustomVisibility", typeof(bool), typeof(WPFCustomVisibilityBehavior), new PropertyMetadata(false));
public string VisibilityGroupName
{
get { return (string)GetValue(VisibilityGroupNameProperty); }
set { SetValue(VisibilityGroupNameProperty, value); }
}
public static readonly DependencyProperty VisibilityGroupNameProperty = DependencyProperty.Register("VisibilityGroupName", typeof(string), typeof(WPFCustomVisibilityBehavior), new PropertyMetadata(string.Empty));
public Dictionary<string, bool> VisibilityDictionary
{
get { return (Dictionary<string, bool>)GetValue(VisibilityDictionaryProperty); }
set { SetValue(VisibilityDictionaryProperty, value); }
}
public static readonly DependencyProperty VisibilityDictionaryProperty = DependencyProperty.Register("VisibilityDictionary", typeof(Dictionary<string, bool>), typeof(WPFCustomVisibilityBehavior), new PropertyMetadata(new Dictionary<string, bool>()));
#endregion
#region Constructor
#endregion
#region Overrrides
protected override void OnAttached()
{
base.OnAttached();
if (this.AllowCustomVisibility == false)
{
return;
}
this._control = this.AssociatedObject as Control;
if (!string.IsNullOrEmpty(this.VisibilityGroupName) && this._control != null)
{
if (this.VisibilityDictionary.ContainsKey(this.VisibilityGroupName))
{
if (this.VisibilityDictionary[this.VisibilityGroupName])
{
this._control.Visibility = Visibility.Visible;
}
else
{
this._control.Visibility = Visibility.Collapsed;
}
}
else
{
this.VisibilityDictionary.Add(this.VisibilityGroupName, this._control.Visibility == Visibility.Visible ? true : false);
}
// Add a ContextMenu to the Control, but only if it does not already have one (TextBox brings its default ContextMenu for copy, cut and paste)
if (this._control.ContextMenu == null && !(this._control is TextBox))
{
this._contextMenu = new ContextMenu();
ContextMenuService.SetContextMenu(this._control, this._contextMenu);
this._control.ContextMenuOpening += (sender, e) => { ContextMenuOpening(e); };
}
}
}
#endregion
#region Event handling
private void ContextMenuOpening(ContextMenuEventArgs e)
{
if (this._contextMenuIsBuilt == false)
{
this._contextMenu.Items.Clear();
Dictionary<string, MenuItem> menuItems = new Dictionary<string, MenuItem>();
foreach (string k in this.VisibilityDictionary.Keys)
{
MenuItem menuItem = new MenuItem() { Header = k, Name = k, IsCheckable = true, StaysOpenOnClick = true };
menuItem.Click += MenuItem_Click;
menuItems.Add(k, menuItem);
}
var keyList = menuItems.Keys.ToList();
keyList.Sort();
foreach (string key in keyList)
{
this._contextMenu.Items.Add(menuItems[key]);
}
this._contextMenuIsBuilt = true;
}
foreach (MenuItem mi in this._contextMenu.Items)
{
mi.IsChecked = this.VisibilityDictionary[mi.Name];
}
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
this.VisibilityDictionary[this.VisibilityGroupName] = mi.IsChecked;
//TODO: Let all suscribing controls know that the Visibility for a group was changed in the VisibilityDictionary => this should call GroupVisibilityWasChanged()...
}
private void GroupVisibilityWasChanged()
{
if (this.VisibilityDictionary[this.VisibilityGroupName])
{
this._control.Visibility = Visibility.Visible;
}
else
{
this._control.Visibility = Visibility.Collapsed;
}
}
#endregion
}
}