223 lines
6.3 KiB
C#
223 lines
6.3 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Collections.Generic;
|
|
using System.Windows.Forms;
|
|
using System.Reflection;
|
|
|
|
namespace Csla.Windows
|
|
{
|
|
/// <summary>
|
|
/// Windows Forms extender control that automatically
|
|
/// enables and disables detail form controls based
|
|
/// on the authorization settings from a CSLA .NET
|
|
/// business object.
|
|
/// </summary>
|
|
[DesignerCategory("")]
|
|
[ProvideProperty("ApplyAuthorization", typeof(Control))]
|
|
public class ReadWriteAuthorization : Component, IExtenderProvider
|
|
{
|
|
|
|
private Dictionary<Control, bool> _sources =
|
|
new Dictionary<Control, bool>();
|
|
|
|
/// <summary>
|
|
/// Creates an instance of the object.
|
|
/// </summary>
|
|
/// <param name="container">The container of the control.</param>
|
|
public ReadWriteAuthorization(IContainer container)
|
|
{ container.Add(this); }
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether the extender control
|
|
/// can extend the specified control.
|
|
/// </summary>
|
|
/// <param name="extendee">The control to be extended.</param>
|
|
/// <remarks>
|
|
/// Any control implementing either a ReadOnly property or
|
|
/// Enabled property can be extended.
|
|
/// </remarks>
|
|
public bool CanExtend(object extendee)
|
|
{
|
|
if (IsPropertyImplemented(extendee, "ReadOnly")
|
|
|| IsPropertyImplemented(extendee, "Enabled"))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the custom ApplyAuthorization extender
|
|
/// property added to extended controls.
|
|
/// </summary>
|
|
/// <param name="source">Control being extended.</param>
|
|
public bool GetApplyAuthorization(Control source)
|
|
{
|
|
if (_sources.ContainsKey(source))
|
|
return _sources[source];
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the custom ApplyAuthorization extender
|
|
/// property added to extended controls.
|
|
/// </summary>
|
|
/// <param name="source">Control being extended.</param>
|
|
/// <param name="value">New value of property.</param>
|
|
public void SetApplyAuthorization(Control source, bool value)
|
|
{
|
|
if (_sources.ContainsKey(source))
|
|
_sources[source] = value;
|
|
else
|
|
_sources.Add(source, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Causes the ReadWriteAuthorization control
|
|
/// to apply authorization rules from the business
|
|
/// object to all extended controls on the form.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Call this method to refresh the display of detail
|
|
/// controls on the form any time the authorization
|
|
/// rules may have changed. Examples include: after
|
|
/// a user logs in or out, and after an object has
|
|
/// been updated, inserted, deleted or retrieved
|
|
/// from the database.
|
|
/// </remarks>
|
|
public void ResetControlAuthorization()
|
|
{
|
|
foreach (KeyValuePair<Control, bool> item in _sources)
|
|
{
|
|
if (item.Value)
|
|
{
|
|
// apply authorization rules
|
|
ApplyAuthorizationRules(item.Key);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyAuthorizationRules(Control control)
|
|
{
|
|
foreach (Binding binding in control.DataBindings)
|
|
{
|
|
// get the BindingSource if appropriate
|
|
if (binding.DataSource is BindingSource)
|
|
{
|
|
BindingSource bs =
|
|
(BindingSource)binding.DataSource;
|
|
// get the BusinessObject if appropriate
|
|
Csla.Security.IAuthorizeReadWrite ds =
|
|
bs.Current as Csla.Security.IAuthorizeReadWrite;
|
|
if (ds != null)
|
|
{
|
|
// get the object property name
|
|
string propertyName =
|
|
binding.BindingMemberInfo.BindingField;
|
|
|
|
ApplyReadRules(
|
|
control, binding,
|
|
ds.CanReadProperty(propertyName));
|
|
ApplyWriteRules(
|
|
control, binding,
|
|
ds.CanWriteProperty(propertyName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyReadRules(
|
|
Control ctl, Binding binding,
|
|
bool canRead)
|
|
{
|
|
// enable/disable reading of the value
|
|
if (canRead)
|
|
{
|
|
bool couldRead = ctl.Enabled;
|
|
ctl.Enabled = true;
|
|
binding.Format -=
|
|
new ConvertEventHandler(ReturnEmpty);
|
|
if (!couldRead) binding.ReadValue();
|
|
}
|
|
else
|
|
{
|
|
ctl.Enabled = false;
|
|
binding.Format +=
|
|
new ConvertEventHandler(ReturnEmpty);
|
|
|
|
// clear the value displayed by the control
|
|
PropertyInfo propertyInfo =
|
|
ctl.GetType().GetProperty(binding.PropertyName,
|
|
BindingFlags.FlattenHierarchy |
|
|
BindingFlags.Instance |
|
|
BindingFlags.Public);
|
|
if (propertyInfo != null)
|
|
{
|
|
propertyInfo.SetValue(ctl,
|
|
GetEmptyValue(
|
|
Utilities.GetPropertyType(
|
|
propertyInfo.PropertyType)),
|
|
new object[] { });
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyWriteRules(
|
|
Control ctl, Binding binding,
|
|
bool canWrite)
|
|
{
|
|
if (ctl is Label) return;
|
|
|
|
// enable/disable writing of the value
|
|
PropertyInfo propertyInfo =
|
|
ctl.GetType().GetProperty("ReadOnly",
|
|
BindingFlags.FlattenHierarchy |
|
|
BindingFlags.Instance |
|
|
BindingFlags.Public);
|
|
if (propertyInfo != null)
|
|
{
|
|
bool couldWrite =
|
|
(!(bool)propertyInfo.GetValue(
|
|
ctl, new object[] { }));
|
|
propertyInfo.SetValue(
|
|
ctl, !canWrite, new object[] { });
|
|
if ((!couldWrite) && (canWrite))
|
|
binding.ReadValue();
|
|
}
|
|
else
|
|
{
|
|
bool couldWrite = ctl.Enabled;
|
|
ctl.Enabled = canWrite;
|
|
if ((!couldWrite) && (canWrite))
|
|
binding.ReadValue();
|
|
}
|
|
}
|
|
|
|
private void ReturnEmpty(
|
|
object sender, ConvertEventArgs e)
|
|
{
|
|
e.Value = GetEmptyValue(e.DesiredType);
|
|
}
|
|
|
|
private object GetEmptyValue(Type desiredType)
|
|
{
|
|
object result = null;
|
|
if (desiredType.IsValueType)
|
|
result = Activator.CreateInstance(desiredType);
|
|
return result;
|
|
}
|
|
|
|
private static bool IsPropertyImplemented(
|
|
object obj, string propertyName)
|
|
{
|
|
if (obj.GetType().GetProperty(propertyName,
|
|
BindingFlags.FlattenHierarchy |
|
|
BindingFlags.Instance |
|
|
BindingFlags.Public) != null)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
}
|