Skip to content

A C# utility library providing helpful extension methods for WPF applications, focusing on visual tree navigation and manipulation.

Notifications You must be signed in to change notification settings

olivegamestudio/OliveStudio.WPF

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OliveStudio.WPF

A C# utility library providing helpful extension methods for WPF applications, focusing on visual tree navigation and manipulation.

Installation

# Package manager
Install-Package OliveStudio.WPF

# .NET CLI
dotnet add package OliveStudio.WPF

Requirements

  • .NET Framework 4.6.1 or later
  • WPF (Windows Presentation Foundation)

Extension Methods

DependencyObjectExtensions

Extension methods for DependencyObject that simplify visual tree navigation in WPF applications.

FindParentOfType<TDependencyType>()

Finds the first parent of a specified type by traversing up the visual tree.

public static TDependencyType? FindParentOfType<TDependencyType>(this DependencyObject dependencyObject)

Parameters:

  • dependencyObject - The dependency object to start the search from

Returns:

  • The first parent of the specified type, or null if no such parent exists

FindVisualChildrenOfType<TDependencyType>()

Finds all visual children of a specified type by recursively searching down the visual tree.

public static List<TDependencyType> FindVisualChildrenOfType<TDependencyType>(this DependencyObject dependencyObject) 
    where TDependencyType : DependencyObject

Parameters:

  • dependencyObject - The parent dependency object to search within

Returns:

  • A list of all visual children of the specified type

Usage Examples

Finding Parent Controls

using OliveStudio;

// In a button click event handler
private void Button_Click(object sender, RoutedEventArgs e)
{
    var button = sender as Button;
    
    // Find the parent Window
    var parentWindow = button.FindParentOfType<Window>();
    if (parentWindow != null)
    {
        parentWindow.Title = "Button was clicked!";
    }
    
    // Find the parent Grid
    var parentGrid = button.FindParentOfType<Grid>();
    if (parentGrid != null)
    {
        parentGrid.Background = Brushes.LightBlue;
    }
    
    // Find parent UserControl
    var parentUserControl = button.FindParentOfType<UserControl>();
    if (parentUserControl != null)
    {
        // Access parent UserControl's properties or methods
        ((MyUserControl)parentUserControl).DoSomething();
    }
}

Finding Child Controls

using OliveStudio;

// In a Window or UserControl
private void FindAllTextBoxes()
{
    // Find all TextBox controls in the current window
    var textBoxes = this.FindVisualChildrenOfType<TextBox>();
    
    foreach (var textBox in textBoxes)
    {
        textBox.Background = Brushes.Yellow;
        Console.WriteLine($"Found TextBox: {textBox.Name}");
    }
}

private void ValidateAllInputs()
{
    // Find all TextBox controls for validation
    var textBoxes = this.FindVisualChildrenOfType<TextBox>();
    
    bool allValid = true;
    foreach (var textBox in textBoxes)
    {
        if (string.IsNullOrWhiteSpace(textBox.Text))
        {
            textBox.BorderBrush = Brushes.Red;
            allValid = false;
        }
        else
        {
            textBox.BorderBrush = Brushes.Green;
        }
    }
    
    if (allValid)
    {
        MessageBox.Show("All inputs are valid!");
    }
}

Working with Custom Controls

// Custom UserControl
public partial class CustomerEditor : UserControl
{
    // Find specific child controls
    private void InitializeControls()
    {
        var nameTextBox = this.FindVisualChildrenOfType<TextBox>()
            .FirstOrDefault(tb => tb.Name == "NameTextBox");
            
        var saveButtons = this.FindVisualChildrenOfType<Button>()
            .Where(b => b.Content?.ToString()?.Contains("Save") == true);
            
        foreach (var button in saveButtons)
        {
            button.Click += SaveButton_Click;
        }
    }
}

// Usage in parent window
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Find all CustomerEditor controls
    var customerEditors = this.FindVisualChildrenOfType<CustomerEditor>();
    
    foreach (var editor in customerEditors)
    {
        // Configure each editor
        editor.IsEnabled = CurrentUser.CanEditCustomers;
    }
}

MVVM Integration

// In a View's code-behind or attached behavior
public class TextBoxValidationBehavior
{
    public static void ValidateAllTextBoxes(DependencyObject parent)
    {
        var textBoxes = parent.FindVisualChildrenOfType<TextBox>();
        
        foreach (var textBox in textBoxes)
        {
            // Trigger validation on each TextBox
            var bindingExpression = textBox.GetBindingExpression(TextBox.TextProperty);
            bindingExpression?.UpdateSource();
        }
    }
}

// Usage in ViewModel command
public class MainWindowViewModel
{
    public ICommand ValidateCommand => new RelayCommand(() =>
    {
        // Access the view through a service or event
        ValidationRequested?.Invoke();
    });
    
    public event Action ValidationRequested;
}

// In View code-behind
private void ViewModel_ValidationRequested()
{
    TextBoxValidationBehavior.ValidateAllTextBoxes(this);
}

Dynamic UI Generation

public class ControlManager
{
    public void DisableAllButtons(Window window)
    {
        var buttons = window.FindVisualChildrenOfType<Button>();
        foreach (var button in buttons)
        {
            button.IsEnabled = false;
        }
    }
    
    public void ApplyThemeToControls(DependencyObject root, Brush foreground, Brush background)
    {
        // Apply to TextBoxes
        var textBoxes = root.FindVisualChildrenOfType<TextBox>();
        foreach (var textBox in textBoxes)
        {
            textBox.Foreground = foreground;
            textBox.Background = background;
        }
        
        // Apply to Labels
        var labels = root.FindVisualChildrenOfType<Label>();
        foreach (var label in labels)
        {
            label.Foreground = foreground;
        }
    }
    
    public List<T> GetControlsWithTag<T>(DependencyObject root, object tag) where T : FrameworkElement
    {
        var controls = root.FindVisualChildrenOfType<T>();
        return controls.Where(c => Equals(c.Tag, tag)).ToList();
    }
}

Event Handling Scenarios

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        SetupEventHandlers();
    }
    
    private void SetupEventHandlers()
    {
        // Find all buttons and attach a common handler
        var buttons = this.FindVisualChildrenOfType<Button>();
        foreach (var button in buttons)
        {
            button.MouseEnter += Button_MouseEnter;
            button.MouseLeave += Button_MouseLeave;
        }
        
        // Find all TextBoxes and attach validation
        var textBoxes = this.FindVisualChildrenOfType<TextBox>();
        foreach (var textBox in textBoxes)
        {
            textBox.LostFocus += TextBox_LostFocus;
        }
    }
    
    private void Button_MouseEnter(object sender, MouseEventArgs e)
    {
        if (sender is Button button)
        {
            var parentPanel = button.FindParentOfType<Panel>();
            parentPanel?.Children.OfType<TextBlock>()
                .FirstOrDefault()?.SetValue(TextBlock.TextProperty, $"Hovering over {button.Content}");
        }
    }
    
    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        if (sender is TextBox textBox)
        {
            // Find parent form for validation
            var parentWindow = textBox.FindParentOfType<Window>();
            UpdateValidationStatus(parentWindow);
        }
    }
}

About

A C# utility library providing helpful extension methods for WPF applications, focusing on visual tree navigation and manipulation.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages