WPF - 从代码中获取所有 children
WPF - get all children from code
这是我的问题:我用 Fluent ribbon 创建了一个程序,当我想禁用 ribbon 时,我需要使用以下代码:
WPF 代码:
<Fluent:RibbonGroupBox x:Name="GpRibbonFormats" ...>
<Fluent:Button x:Name="AjoutTole" Header="{x:Static p:Resources.Ajouter}">
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipAjoutTole"...>
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
<Fluent:Button x:Name="EditQtyFormat" ...>
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipEditQtyFormat"...>
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
<Fluent:Button x:Name="DeleteFormat" SizeDefinition="Large">
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipDeleteFormat" ...>
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
</Fluent:RibbonGroupBox>
代码隐藏:
AjoutTole.IsEnabled = false;
ScreenTipAjoutTole.DisableReason = isBlocked;
EditQtyFormat.IsEnabled = false;
ScreenTipEditQtyFormat.DisableReason = isBlocked;
DeleteFormat.IsEnabled = false;
ScreenTipDeleteFormat.DisableReason = isBlocked;
它工作正常,但我想做一个这样的功能,所以我确信我总是在 DisableReason 中发送正确的信息:
DisableButton(Fluent:Button NameOfButton,string ReasonOfDisable)
{
NameOfButton.IsEnabled = false;
NameOfButton.AllScreenTipChild.DisableReason=ReasonOfDisable
}
我想以同样的方式禁用所有一组按钮:
DisableGroup(Fluent:RibbonGroupBox myGroup,string ReasonOfDisable)
{
foreach(Fluent:Button button in myGroup)
{
button.isEnable=false;
button.AllScreenTipChild.DisableReason=ReasonOfDisable;
}
}
这怎么可能?我希望能够从代码隐藏中做到这一点。
编辑:
当试图获取按钮的 children 时,我 return 类型为 System.Windows.Controls.Border 的一个元素,名称为 "border",但我没有我的 XAML 文件中的此类元素。
我还尝试获取我的 RibbonGroupBox 的 children,但在那种情况下我 return 一个网格 (grid2),并且该网格甚至不在功能区中...
使用的代码:
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(DeleteOL); i++)
{
var child = VisualTreeHelper.GetChild(DeleteOL, i);
string monType = child.GetType().ToString();
if(monType== "System.Windows.Controls.Border")
{
System.Windows.Controls.Border bb = (System.Windows.Controls.Border)child;
string name = bb.Name;
}
}
编辑 2 :
我确认 getChild 在功能区上不起作用(为什么?),但我可以找到如何获取组中的按钮列表:
foreach(var item in GpRibbonFormats.Items)
{
if(item.GetType().ToString()=="Fluent.Button")
{
Fluent.Button button = (Fluent.Button)item;
button.IsEnabled = false;
}
}
现在我还在研究如何找到按钮的屏幕提示
您似乎混合了 XAML 和 C# 的命名空间约定,在 C# 中您不使用 :
来引用命名空间,而是使用 .
分隔符。例如,StackPanel
位于 System.Windows.Controls
命名空间内,因此在 C# 中可以这样引用它:
System.Windows.Controls.StackPanel stackPanel = new System.Windows.Controls.StackPanel();
我从未尝试过 Fluent,但这段代码应该可以。
public void DisableGroup(Fluent.RibbonGroupBox ribbonGroup, string reasonOfDisable)
{
foreach (var item in ribbonGroup.Items)
{
if (item is Fluent.Button)
{
DisableButton((Fluent.Button)item, reasonOfDisable);
}
}
}
public void DisableButton(Fluent.Button button, string reasonOfDisable)
{
button.IsEnabled = false;
if (button.ToolTip is Fluent.ScreenTip)
{
Fluent.ScreenTip screenTip = (Fluent.ScreenTip)button.ToolTip;
screenTip.DisableReason = reasonOfDisable;
}
}
要禁用整个组,您可以这样称呼它
DisableGroup(GpRibbonFormats, "Ce groupe n'est pas disponible");
只禁用一个按钮,你可以这样称呼它
DisableButton(AjoutTole, "Ajouter est désactivé pour le moment");
顺便说一下,Fluent.RibbonGroupBox
继承自 ItemsControl
,此控件有自己的 IsEnabled
属性,您只需设置 属性 设置为 false(虽然我还没有测试过),但是无论如何你都必须通过每个按钮来设置它们的屏幕提示。
GpRibbonFormats.IsEnabled = false;
对于这种东西,Binding
在WPF中是非常强大的,你可能想看一下MVVM。一开始实施起来并不容易,但一旦掌握了它,它就会改变游戏规则,真正简化您的代码和逻辑。
我花了一些时间,但我终于理解了用户试图向我解释的内容(对于开始使用 MVVM 的人来说这并不明显,这就是我写在这里的原因)。
我相信我可以在代码中轻松地将我的属性 IsEnabled 设置为 true 或 false(如 Roger Leblanc 的回答),然后继续绑定我的 ViewModel。
事实并非如此,因为当我设置 IsEnable(为 true)属性 时,它用 IsEnabled=true 替换了 IsEnabled="{Binding EnableEditNesting}" ,所以之后不再进行绑定(如果我错了请告诉我)。
最后我做了以下事情:
对于不需要每个按钮有不同行为的 GroupBox,我只是在其 IsEnable 参数上绑定。
<Fluent:RibbonGroupBox x:Name="GpRibbonFormats" IsEnabled="{Binding EnableGpRibbonFormats}" Header="{x:Static p:Resources.Stock}">
<Fluent:RibbonGroupBox.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipGpRibbonFormats" Image="img\image_engrenage.png" Width="250" Text="{x:Static p:Resources.NestingSendToProduction}" DisableReason="{Binding EnableGpRibbonFormatsReason}">
</Fluent:ScreenTip>
</Fluent:RibbonGroupBox.ToolTip>
<Fluent:Button x:Name="AjoutTole" SizeDefinition="Large" LargeIcon="img\image_add.png" Header="{x:Static p:Resources.Ajouter}" Click="Add_ToleOL_Click">
</Fluent:Button>
...
</Fluent:RibbonGroupBox>
对于我需要在每个按钮上有特定行为的 GrouBox,我为每个按钮设置了一个绑定(组中没有任何内容),当我需要禁用所有组时,我然后一个一个禁用按钮。
<Fluent:RibbonGroupBox x:Name="GpRibbonOL" Header="{x:Static p:Resources.NestingLaunchingOrder}">
<Fluent:Button x:Name="DeleteOL" IsEnabled="{Binding EnableDeleteOL}" SizeDefinition="Large" LargeIcon="img\image_delete.png" Header="{x:Static p:Resources.Supprimer}" Click="Supprimer_OF">
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipDeleteOL" Image="img\image_delete.png" Title="Delete OL" Width="250" Text="Delete element" DisableReason="{Binding EnableEditNestingReason}">
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
...
</Fluent:RibbonGroupBox>
ViewModel 看起来像那样,所以当我想要 Enable/Disable 时,我只需更改工具提示即可:
private bool enableGpRibbonNesting;
public bool EnableGpRibbonNesting
{
get { return enableGpRibbonNesting; }
set
{
enableGpRibbonNesting = value;
this.NotifyPropertyChanged("EnableGpRibbonNesting");
}
}
private string enableGpRibbonNestingReason;
public string EnableGpRibbonNestingReason
{
get { return enableGpRibbonNestingReason; }
set
{
enableGpRibbonNestingReason = value;
if (value == "")
{
EnableGpRibbonNesting = true;
}
else
{
EnableGpRibbonNesting = false;
}
this.NotifyPropertyChanged("EnableGpRibbonNestingReason");
}
}
这是我的问题:我用 Fluent ribbon 创建了一个程序,当我想禁用 ribbon 时,我需要使用以下代码:
WPF 代码:
<Fluent:RibbonGroupBox x:Name="GpRibbonFormats" ...>
<Fluent:Button x:Name="AjoutTole" Header="{x:Static p:Resources.Ajouter}">
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipAjoutTole"...>
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
<Fluent:Button x:Name="EditQtyFormat" ...>
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipEditQtyFormat"...>
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
<Fluent:Button x:Name="DeleteFormat" SizeDefinition="Large">
<Fluent:Button.ToolTip>
<Fluent:ScreenTip x:Name="ScreenTipDeleteFormat" ...>
</Fluent:ScreenTip>
</Fluent:Button.ToolTip>
</Fluent:Button>
</Fluent:RibbonGroupBox>
代码隐藏:
AjoutTole.IsEnabled = false;
ScreenTipAjoutTole.DisableReason = isBlocked;
EditQtyFormat.IsEnabled = false;
ScreenTipEditQtyFormat.DisableReason = isBlocked;
DeleteFormat.IsEnabled = false;
ScreenTipDeleteFormat.DisableReason = isBlocked;
它工作正常,但我想做一个这样的功能,所以我确信我总是在 DisableReason 中发送正确的信息:
DisableButton(Fluent:Button NameOfButton,string ReasonOfDisable)
{
NameOfButton.IsEnabled = false;
NameOfButton.AllScreenTipChild.DisableReason=ReasonOfDisable
}
我想以同样的方式禁用所有一组按钮:
DisableGroup(Fluent:RibbonGroupBox myGroup,string ReasonOfDisable)
{
foreach(Fluent:Button button in myGroup)
{
button.isEnable=false;
button.AllScreenTipChild.DisableReason=ReasonOfDisable;
}
}
这怎么可能?我希望能够从代码隐藏中做到这一点。
编辑:
当试图获取按钮的 children 时,我 return 类型为 System.Windows.Controls.Border 的一个元素,名称为 "border",但我没有我的 XAML 文件中的此类元素。 我还尝试获取我的 RibbonGroupBox 的 children,但在那种情况下我 return 一个网格 (grid2),并且该网格甚至不在功能区中...
使用的代码:
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(DeleteOL); i++)
{
var child = VisualTreeHelper.GetChild(DeleteOL, i);
string monType = child.GetType().ToString();
if(monType== "System.Windows.Controls.Border")
{
System.Windows.Controls.Border bb = (System.Windows.Controls.Border)child;
string name = bb.Name;
}
}
编辑 2 :
我确认 getChild 在功能区上不起作用(为什么?),但我可以找到如何获取组中的按钮列表:
foreach(var item in GpRibbonFormats.Items)
{
if(item.GetType().ToString()=="Fluent.Button")
{
Fluent.Button button = (Fluent.Button)item;
button.IsEnabled = false;
}
}
现在我还在研究如何找到按钮的屏幕提示
您似乎混合了 XAML 和 C# 的命名空间约定,在 C# 中您不使用 :
来引用命名空间,而是使用 .
分隔符。例如,StackPanel
位于 System.Windows.Controls
命名空间内,因此在 C# 中可以这样引用它:
System.Windows.Controls.StackPanel stackPanel = new System.Windows.Controls.StackPanel();
我从未尝试过 Fluent,但这段代码应该可以。
public void DisableGroup(Fluent.RibbonGroupBox ribbonGroup, string reasonOfDisable)
{
foreach (var item in ribbonGroup.Items)
{
if (item is Fluent.Button)
{
DisableButton((Fluent.Button)item, reasonOfDisable);
}
}
}
public void DisableButton(Fluent.Button button, string reasonOfDisable)
{
button.IsEnabled = false;
if (button.ToolTip is Fluent.ScreenTip)
{
Fluent.ScreenTip screenTip = (Fluent.ScreenTip)button.ToolTip;
screenTip.DisableReason = reasonOfDisable;
}
}
要禁用整个组,您可以这样称呼它
DisableGroup(GpRibbonFormats, "Ce groupe n'est pas disponible");
只禁用一个按钮,你可以这样称呼它
DisableButton(AjoutTole, "Ajouter est désactivé pour le moment");
顺便说一下,Fluent.RibbonGroupBox
继承自 ItemsControl
,此控件有自己的 IsEnabled
属性,您只需设置 属性 设置为 false(虽然我还没有测试过),但是无论如何你都必须通过每个按钮来设置它们的屏幕提示。
GpRibbonFormats.IsEnabled = false;
对于这种东西,Binding
在WPF中是非常强大的,你可能想看一下MVVM。一开始实施起来并不容易,但一旦掌握了它,它就会改变游戏规则,真正简化您的代码和逻辑。
我花了一些时间,但我终于理解了用户试图向我解释的内容(对于开始使用 MVVM 的人来说这并不明显,这就是我写在这里的原因)。
我相信我可以在代码中轻松地将我的属性 IsEnabled 设置为 true 或 false(如 Roger Leblanc 的回答),然后继续绑定我的 ViewModel。 事实并非如此,因为当我设置 IsEnable(为 true)属性 时,它用 IsEnabled=true 替换了 IsEnabled="{Binding EnableEditNesting}" ,所以之后不再进行绑定(如果我错了请告诉我)。
最后我做了以下事情:
对于不需要每个按钮有不同行为的 GroupBox,我只是在其 IsEnable 参数上绑定。
<Fluent:RibbonGroupBox x:Name="GpRibbonFormats" IsEnabled="{Binding EnableGpRibbonFormats}" Header="{x:Static p:Resources.Stock}"> <Fluent:RibbonGroupBox.ToolTip> <Fluent:ScreenTip x:Name="ScreenTipGpRibbonFormats" Image="img\image_engrenage.png" Width="250" Text="{x:Static p:Resources.NestingSendToProduction}" DisableReason="{Binding EnableGpRibbonFormatsReason}"> </Fluent:ScreenTip> </Fluent:RibbonGroupBox.ToolTip> <Fluent:Button x:Name="AjoutTole" SizeDefinition="Large" LargeIcon="img\image_add.png" Header="{x:Static p:Resources.Ajouter}" Click="Add_ToleOL_Click"> </Fluent:Button> ... </Fluent:RibbonGroupBox>
对于我需要在每个按钮上有特定行为的 GrouBox,我为每个按钮设置了一个绑定(组中没有任何内容),当我需要禁用所有组时,我然后一个一个禁用按钮。
<Fluent:RibbonGroupBox x:Name="GpRibbonOL" Header="{x:Static p:Resources.NestingLaunchingOrder}"> <Fluent:Button x:Name="DeleteOL" IsEnabled="{Binding EnableDeleteOL}" SizeDefinition="Large" LargeIcon="img\image_delete.png" Header="{x:Static p:Resources.Supprimer}" Click="Supprimer_OF"> <Fluent:Button.ToolTip> <Fluent:ScreenTip x:Name="ScreenTipDeleteOL" Image="img\image_delete.png" Title="Delete OL" Width="250" Text="Delete element" DisableReason="{Binding EnableEditNestingReason}"> </Fluent:ScreenTip> </Fluent:Button.ToolTip> </Fluent:Button> ... </Fluent:RibbonGroupBox>
ViewModel 看起来像那样,所以当我想要 Enable/Disable 时,我只需更改工具提示即可:
private bool enableGpRibbonNesting;
public bool EnableGpRibbonNesting
{
get { return enableGpRibbonNesting; }
set
{
enableGpRibbonNesting = value;
this.NotifyPropertyChanged("EnableGpRibbonNesting");
}
}
private string enableGpRibbonNestingReason;
public string EnableGpRibbonNestingReason
{
get { return enableGpRibbonNestingReason; }
set
{
enableGpRibbonNestingReason = value;
if (value == "")
{
EnableGpRibbonNesting = true;
}
else
{
EnableGpRibbonNesting = false;
}
this.NotifyPropertyChanged("EnableGpRibbonNestingReason");
}
}