Question

I am trying to create a window to act as a switch board for testing an application I'm working on, and having two problems doing so.

The first problem is trying to set the size & margin of buttons that need to be added to a stack panel dynamically. In XAML, the properties look like this:

<StackPanel Name="_mainStackPanel" >
    <Button Height="Auto" Width="Auto" Margin="10,10,10,5" >Do Something</Button>
</StackPanel>

The second problem is trickier. I want the switch board window to have a status bar with an exposed property, like so:

<StatusBar BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
    <TextBlock Name="_statusBar" Foreground="Black" TextWrapping="Wrap">blah</TextBlock>
</StatusBar>

public string Status {
        get { return _statusBar.Text; } 
        set { _statusBar.Text = value; }
}

In a test case I'm working through, I just want each button to display it's text content in the status bar when it's clicked. Invoking the click gets a NullReferenceException...

I'm using the command pattern to tell the button what to do when it's clicked. Here's the code in the switch board window where commands are turned into buttons:

private void _addButtons() {
        foreach (var cmd in _commands)
        {
            var b = new Button
                    {
                        Content = cmd.DisplayText,
                        // height = "Auto" double.NaN ?
                        // width = "Auto"
                        // margin = "10,10,10,5
                    };
            var command = cmd;
            b.Click += ((sender, args) => command.Execute());
            _mainStackPanel.Children.Add(b);
        }
    }

And here is the setup in my "test" (I am not asserting anything, just firing up the gui and seeing if it works):

[TestFixture]
public class SwitchBoardTests
{
    private SwitchBoardView _switchboard;
    private Application _app;

    [SetUp]
    public void SetUp() {
        var commands = new List<IDisplayableCommand> {
                                                         new StatusCommand("Hello...", _switchboard),
                                                         new StatusCommand("Good Bye...", _switchboard),
                                                     };
        _switchboard = new SwitchBoardView(commands);
    }

    class StatusCommand : DisplayCommand
    {
        private readonly SwitchBoardView _view;
        public StatusCommand(string message, SwitchBoardView view) : base(message) {
            _view = view;
        }
        public override void Execute() { _view.Status = DisplayText; }
    }

    [Test]
    public void Display() {
        _app = new Application();
        _app.Run(_switchboard);
        //_switchboard.Show();
    }

}

I am just learning WPF, so any best practices that might come out of solving these two issues would be most welcome!

Cheers,
Berryl

Was it helpful?

Solution

For your dynamic adding of buttons, you could make an ItemsControl instead of a StackPanel and bind the ItemsSource to your list of things to create buttons for (ObservableCollection). You'll also need a DataTemplate to define the ItemsTemplate for your list so that each item appears as a button with the margin and command attribute you want.

Here is a good example of binding an ItemsControl to a template

WPF: Example of ItemsControl bound to an ObservableCollection

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top