views:

176

answers:

1
+1  Q: 

wpf dynamic window

Hello

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

+2  A: 

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

Christopher Scott