EngineerSpock
EngineerSpock

Reputation: 2675

Choosing WPF controls

I need to provide for users the option to change logging level of NLog rules.

There are 12 rules and each one has it's own logging level.

Which controls could you recommend to use to provide this option in WPF?

Upvotes: 1

Views: 119

Answers (1)

Fede
Fede

Reputation: 44068

I'm not familiar with NLog, but I guess if you must pick between a small amount of pre-determined options then a ComboBox is the best UI element for that.

You said you have 12 Log Levels, So in that case it makes most sense to use an ItemsControl to actually show these items instead of creating all the UI elements yourself:

<Window x:Class="MiscSamples.LogLevelsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="LogLevels" Height="300" Width="300">
    <ItemsControl ItemsSource="{Binding LogRules}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Width="100" Margin="2" Text="{Binding Name}"/>
                    <ComboBox ItemsSource="{Binding DataContext.LogLevels, RelativeSource={RelativeSource AncestorType=Window}}"
                              SelectedItem="{Binding LogLevel}" Width="100" Margin="2"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

Code Behind:

    public partial class LogLevelsSample : Window
    {
        public LogLevelsSample()
        {
            InitializeComponent();

            DataContext = new LogSettingsViewModel();
        }
    }

ViewModel:

    public class LogSettingsViewModel
    {
        public List<LogLevels> LogLevels { get; set; }

        public List<LogRule> LogRules { get; set; } 

        public LogSettingsViewModel()
        {
            LogLevels = Enum.GetValues(typeof (LogLevels)).OfType<LogLevels>().ToList();

            LogRules = Enumerable.Range(1, 12).Select(x => new LogRule()
                                                               {
                                                                   Name = "Log Rule " + x.ToString(),
                                                                   LogLevel = MiscSamples.LogLevels.Debug
                                                               }).ToList();
        }
    }

Data Items:

    public class LogRule
    {
        public string Name { get; set; }

        public LogLevels LogLevel { get; set; }
    }

    public enum LogLevels
    {
        Trace,
        Debug,
        Warn,
        Info,
        Error,
        Fatal
    }

Result:

enter image description here

Things to note:

  • I see you have several unanswered WPF questions and you look quite frustrated about it. Don't be. It's a beautiful and excellent framework to work with. I created this example in the hope you can see the real beauty of it. There's no chance you can achieve this same example in winforms without a LOT more code and effort.
  • Take a look at how simple and beautiful this code actually is. I'm doing extensive use of WPF's databinding capabilities and that makes everything a LOT easier.
  • Note there's not a single line of code that references or manipulates any UI element. All I have done is to create the proper data structures and then create the proper UI to display/manipulate it.
  • The "glue" between the data and the UI is the DataContext property, which is what all XAML bindings are resolved against.
  • If you come from winforms or other traditional backgrounds, you really need to forget everything you know from that and embrace MVVM (Click on the link it's not wikipedia).
  • Again, Im not familiar with NLog so I'm not sure whether the data structure I created matches what you need. In any case let me know.
  • Let me know if you need further assistance. I'll be glad to help you in your first steps in WPF.

Upvotes: 1

Related Questions