我正在使用WinForm在C#中创建应用程序。我希望能够使用ctrl + scroll来调整此应用程序内所有标签的字体大小。 目前,我可以在一种表单中更改所有标签的字体,但是我想将此字体大小修改应用于所有表单,而不仅仅是当前表单。
要创建所有表单,我使用的是模板:
public partial class TemplateForm : DockContent
{
static public UInt16 percentageFontSize = 100;
public TemplateForm()
{
InitializeComponent();
}
private void TemplateForm_MouseWheel(object sender, MouseEventArgs e)
{
if (!ModifierKeys.HasFlag(Keys.Control))
{
return;
}
if (e.Delta > 0)
{
percentageFontSize += 10;
if (percentageFontSize >= 2000)
{
percentageFontSize = 2000;
}
}
else
{
percentageFontSize -= 10;
if (percentageFontSize <= 10)
{
percentageFontSize = 10;
}
}
SetAllControlsFont(this.Controls);
}
public static void SetAllControlsFont(System.Windows.Forms.Control.ControlCollection ctrls)
{
foreach (Control ctrl in ctrls)
{
if (ctrl.Controls != null)
SetAllControlsFont(ctrl.Controls);
ctrl.Font = new Font("Microsoft Sans Serif", 8* percentageFontSize / 100);
}
}
}
每个“文档”都使用此模板:
public partial class Form1 : TemplateForm
{
public AccForm()
{
InitializeComponent();
}
}
public partial class Form2 : TemplateForm
{
public AccForm()
{
InitializeComponent();
}
}
“ this.Controls”仅授予我访问所选表单的控件的权限。我想我可以通过使用“ TemplateForm”获取表单的所有控件来实现此目的,但是我无法找到具体方法。您对如何实现这一目标有任何想法吗?
答案 0 :(得分:1)
其他字体不会更改字体大小,而仅在当前格式上更改字体的原因是,由于其他格式无法知道字体大小实际上已更改,因此您必须添加一种方法通知他们,以便他们也可以更新字体大小。 为此,您可以使用EventHandler(或创建您的自定义事件处理程序),将其添加到TemplateForm类中,并在构造函数中进行订阅,每当字体更改时引发事件,并在trigger方法中更新字体相应。 总之,您的代码应如下所示:
static public EventHandler fontSizeChangedEvent;
static public UInt16 percentageFontSize = 100;
public TemplateForm()
{
MouseWheel += TemplateForm_MouseWheel;
fontSizeChangedEvent += FontSizeChanged;
}
private void TemplateForm_MouseWheel(object sender, MouseEventArgs e)
{
//// rest of code .....
fontSizeChangedEvent.Invoke(this, new EventArgs());
SetAllControlsFont();
}
public void FontSizeChanged(object sender, EventArgs e)
{
// Only update for the other forms, not the one that raised the event
if (sender != this)
SetAllControlsFont();
}
public void SetAllControlsFont(ControlCollection ctrls = null)
{
if (ctrls == null)
ctrls = this.Controls;
//// rest of code .....
}
答案 1 :(得分:1)
显然,您设计的概念是“所有标签的唯一字体”。只要您想到一个,就应该想到一个静态类或一个单例。两者都有其优点和缺点。您选择的哪个不在此问题范围内
无论如何,这个也是唯一的LabelFont,都有一种更改字体的方法,一旦设置,就会引发一个事件。
class LabelFont
{
private Font labelFont; // TODO: consider to initialize with a proper default value.
public event EventHandler LabelFontChanged;
protected virtual void OnLabelFontChanged()
{
this.LabelFontChanged?.Invoke(this, EventArgs.Empty);
}
public Font LabelFont
{
get => this.labelFont;
set
{
this.labelFont = value;
this.OnLabelFontChanged;
}
}
}
我们需要一种方法,该方法具有一系列输入控件,然后输出:此一系列控件加上所有子控件和孙控件等
public static IEnumerable<Control> ToDecendants(this IEnumerable<Control> controls)
{
foreach (Control control in controls)
{
// first return this control
yield return control
// then return decendants of the child controls
IEnumerable<Control> decendants = control.Controls
.Cast<Control>();
.ToDecendants();
foreach (Control decendant in decendants)
{
foreach (Control decendant in decendants)
yield return decendant;
}
}
}
也许您可以使用LINQ和SelectMany做一些事情。不要忘记添加控件本身,而不仅仅是添加子控件(SelectMany会这样做)
每一个LableFont发生变化时,都需要通知每个TemplateForm
class TemplateForm
{
private static LabelFont LabelFont => ... // get either static, or singleton
public TemplateForm()
{
...
// get notified when the LableFont changes
LabelFont.LabelFontChanged += OnLabelFontChanged;
}
// TODO: Dispose: desubscribe from LabelFontChanged
private void OnLableFontChanged(object sender, EventArgs e)
{
LabelFont labelFont = (LabelFont) sender; // if singleton, otherwise use static
Font labelFont = labelFont.LabelFont;
IEnumerable<Control> decendants = this.Controls.Cast<Control>
.ToDecendants();
foreach (Control decendant in decendants)
{
decendant.Font = labelFont;
}
}
或者如果您只想更新Label控件的字体:
IEnumerable<Control> labelDecendants= this.Controls
.Cast<Control>
.ToDecendants()
.OfType<Label>();