Search code examples
c#wpffluent-ribbon

WPF - get all children from code


Here is my problem : I created a programm with Fluent ribbon, and when I want to disable a ribbon, I need to use the following code :

Code 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>

Code Behind :

AjoutTole.IsEnabled = false;
ScreenTipAjoutTole.DisableReason = isBlocked;
EditQtyFormat.IsEnabled = false;
ScreenTipEditQtyFormat.DisableReason = isBlocked;
DeleteFormat.IsEnabled = false;
ScreenTipDeleteFormat.DisableReason = isBlocked;

It works fine but I would like to make a function like that, so I am sure I always send correct information in DisableReason :

DisableButton(Fluent:Button NameOfButton,string ReasonOfDisable)
{
    NameOfButton.IsEnabled = false;
    NameOfButton.AllScreenTipChild.DisableReason=ReasonOfDisable
}

The same way I would like to disable all a group of buttons :

DisableGroup(Fluent:RibbonGroupBox myGroup,string ReasonOfDisable)
{
    foreach(Fluent:Button button in myGroup)
    {
        button.isEnable=false;
        button.AllScreenTipChild.DisableReason=ReasonOfDisable;
    }
}

How such a thing is it possible?I want to be able to do it from codebehind.

Edit :

When trying to get the children of my button, I return one element of type System.Windows.Controls.Border, which name is "border", but I don't have such element in my XAML file. I also tried to get children of my RibbonGroupBox, but in that case I return one grid (grid2), and that grid is not even in the Ribbon...

Code used :

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;
   }
}

Edit 2 :

I confirm that getChild doesn't work on ribbon(why?), but I could find how to get list of buttons in a group :

foreach(var item in GpRibbonFormats.Items)
{
    if(item.GetType().ToString()=="Fluent.Button")
    {
         Fluent.Button button = (Fluent.Button)item;
         button.IsEnabled = false;
    }
}

Now I am still looking on how to find a button's ScreenTip


Solution

  • It took time to me, but I finally understood what users were trying to explain to me (it is not obvious for somebody starting with MVVM, that's why I write it here).

    I believed I could easily set my properties IsEnabled to true or false in the code(As in Roger Leblanc answer), then continue binding my ViewModel. It is not so, as when I set my IsEnable (to true) Property, it replaces IsEnabled="{Binding EnableEditNesting}" by IsEnabled=true, so after that no more binding is done(tell me if I am wrong).

    On the end I did the following :

    • For the GroupBox that don't need different behaviour for each button, I just put a binding on its IsEnable parameter.

       <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>
      
    • For the GrouBox where I need specific behaviour on each button, I put a Binding for each of the buttons(nothing on the group), and when I need to disable all the group, I then disable buttons one by one.

      <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 looks like that, so when I want to Enable/Disable, I just change the tooltip :

        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");
    
            }
        }