【发布时间】:2021-09-19 20:07:11
【问题描述】:
我有一个来自 System.Windows.Controls.Control 的基类,它根据外部数据更改 Visibility、Enabled 、Background、Foreground 属性。
当我使用下面的类时
public class RsdDesignBase : Button
{
....
}
它适用于按钮控制。我想为 TextBox、Image、TextBlock 等其他控件使用相同的类,但如果我这样使用,我需要为所有其他控件复制粘贴相同的代码。
有没有办法将我的 RsdDesignBase 类用作其他控件的基类?或任何其他方式来做到这一点。
我将在下面粘贴整个班级。它所做的是等待 DataTag 对象的更改,当它们更改为某些属性时。例如,如果 _enabledTag.Value 为 0,它将禁用控件。
public class RsdDesignButtonBase : Button
{
private DataTag _visibilityTag;
private DataTag _enabledTag;
private DataTag _appearanceTag;
public TagScriptObject TagScriptObject { get; set; }
private readonly Timer _timer;
protected RsdDesignButtonBase()
{
Loaded += RSD_ButtonBase_Loaded;
Unloaded += OnUnloaded;
_timer = new Timer(1000);
_timer.Elapsed += TimerOnElapsed;
}
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
Dispatcher.BeginInvoke(new Action(() =>
{
var background = Background;
var foreground = Foreground;
Background = foreground;
Foreground = background;
}), DispatcherPriority.Render);
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
if (_enabledTag != null) _enabledTag.DataChanged -= EnabledTagOnDataChanged;
if (_visibilityTag != null) _visibilityTag.DataChanged -= VisibilityTagOnDataChanged;
if (_appearanceTag != null) _appearanceTag.DataChanged -= AppearanceTagOnDataChanged;
}
private void RSD_ButtonBase_Loaded(object sender, RoutedEventArgs e)
{
DependencyPropertyDescriptor desc =
DependencyPropertyDescriptor.FromProperty(FrameworkElement.TagProperty, typeof(FrameworkElement));
desc.AddValueChanged(this, TagPropertyChanged);
TagPropertyChanged(null, null);
}
private void TagPropertyChanged(object sender, EventArgs e)
{
if (Tag == null) return;
TagScriptObject = JsonConvert.DeserializeObject<TagScriptObject>(Tag.ToString());
if (TagScriptObject?.VisibilityProperty?.TagId > 0)
{
_visibilityTag =
GlobalVars.AllDataTagList.FirstOrDefault(t => t.Id == TagScriptObject.VisibilityProperty?.TagId);
if (_visibilityTag != null)
{
_visibilityTag.DataChanged += VisibilityTagOnDataChanged;
VisibilityTagOnDataChanged(null, null);
}
}
if (TagScriptObject?.EnableProperty?.TagId > 0)
{
_enabledTag =
GlobalVars.AllDataTagList.FirstOrDefault(t => t.Id == TagScriptObject.EnableProperty?.TagId);
if (_enabledTag != null)
{
_enabledTag.DataChanged += EnabledTagOnDataChanged;
EnabledTagOnDataChanged(null, null);
}
}
if (TagScriptObject?.AppearanceProperty?.TagId > 0)
{
_appearanceTag =
GlobalVars.AllDataTagList.FirstOrDefault(t => t.Id == TagScriptObject.AppearanceProperty?.TagId);
if (_appearanceTag != null && !_appearanceTag.IsEventHandlerRegistered(null))
{
_appearanceTag.DataChanged += AppearanceTagOnDataChanged;
AppearanceTagOnDataChanged(null, null);
}
}
}
private void AppearanceTagOnDataChanged(object source, EventArgs args)
{
_timer.Enabled = false;
_ = Dispatcher.BeginInvoke(new Action(() =>
{
double tagValue;
bool result = true;
if (_appearanceTag.VarType == VarType.Bit)
{
tagValue = _appearanceTag.TagValue ? 1 : 0;
}
else
{
result = double.TryParse(_appearanceTag.TagValue.ToString(), out tagValue);
}
if (result)
{
foreach (var controlColor in TagScriptObject.AppearanceProperty.ControlColors)
{
if (tagValue >= controlColor.RangeMin &&
tagValue <= controlColor.RangeMax)
{
Background =
new BrushConverter().ConvertFromString(controlColor.Background) as SolidColorBrush;
Foreground =
new BrushConverter().ConvertFromString(controlColor.Foreground) as SolidColorBrush;
_timer.Enabled = controlColor.Flashing == ConfirmEnum.Yes;
break;
}
}
}
}), DispatcherPriority.Render);
}
private void EnabledTagOnDataChanged(object source, EventArgs args)
{
_ = Dispatcher.BeginInvoke(new Action(() =>
{
if (_enabledTag != null)
{
if (TagScriptObject.EnableProperty.IsRangeSelected)
{
double tagValue;
bool result = true;
if (_enabledTag.VarType == VarType.Bit)
{
tagValue = _enabledTag.TagValue ? 1 : 0;
}
else
{
result = double.TryParse(_enabledTag.TagValue.ToString(), out tagValue);
}
if (result)
{
if (tagValue >= TagScriptObject.EnableProperty.RangeFrom &&
tagValue <= TagScriptObject.EnableProperty.RangeTo)
{
IsEnabled = TagScriptObject.EnableProperty.DefaultValue;
}
else
{
IsEnabled = !TagScriptObject.EnableProperty.DefaultValue;
}
}
}
else
{
if (_enabledTag.IsNumeric || _enabledTag.VarType == VarType.Bit)
{
var bitArray = _enabledTag.GetBitArray();
var singleBit = TagScriptObject.EnableProperty.SingleBit;
if (bitArray.Count > singleBit)
{
if (bitArray[singleBit])
{
IsEnabled = TagScriptObject.EnableProperty.DefaultValue;
}
else
{
IsEnabled = !TagScriptObject.EnableProperty.DefaultValue;
}
}
}
}
}
}), DispatcherPriority.Render);
}
private void VisibilityTagOnDataChanged(object source, EventArgs args)
{
_ = Dispatcher.BeginInvoke(new Action(() =>
{
if (_visibilityTag != null)
{
if (TagScriptObject.VisibilityProperty.IsRangeSelected)
{
double tagValue;
bool result = true;
if (_visibilityTag.VarType == VarType.Bit)
{
tagValue = _visibilityTag.TagValue ? 1 : 0;
}
else
{
result = double.TryParse(_visibilityTag.TagValue.ToString(), out tagValue);
}
if (result)
{
if (tagValue >= TagScriptObject.VisibilityProperty.RangeFrom &&
tagValue <= TagScriptObject.VisibilityProperty.RangeTo)
{
Visibility = TagScriptObject.VisibilityProperty.DefaultValue
? Visibility.Visible
: Visibility.Hidden;
}
else
{
Visibility = TagScriptObject.VisibilityProperty.DefaultValue
? Visibility.Collapsed
: Visibility.Visible;
}
}
}
else
{
if (_visibilityTag.IsNumeric || _visibilityTag.VarType == VarType.Bit)
{
var bitArray = _visibilityTag.GetBitArray();
var singleBit = TagScriptObject.VisibilityProperty.SingleBit;
if (bitArray.Count > singleBit)
{
if (bitArray[singleBit])
{
Visibility = TagScriptObject.VisibilityProperty.DefaultValue
? Visibility.Visible
: Visibility.Hidden;
}
else
{
Visibility = TagScriptObject.VisibilityProperty.DefaultValue
? Visibility.Hidden
: Visibility.Visible;
}
}
}
}
}
}), DispatcherPriority.Render);
}
}
【问题讨论】:
-
您可能需要重新考虑“根据外部数据更改 Visibility、Enabled、Background、Foreground 属性” 是否值得作为基类来实现。检查附加的行为,这可能会导致在 xaml 中增加一两行,但如果您决定继续,与您现在必须做的工作相比,所需的工作要少得多。您可能还想了解 WPF 的不同 base classes(最好找到一个好的教程/解释它们的书籍),看看您的想法有多糟糕。
标签: c# wpf inheritance wpf-controls