Reputation: 1175
I'm looking for the best way to populate a check boxes from the following code. I have looked into Binding but not really sure where to go.
Here is the edited code that is working
private void dpDateSelection_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
{
DateTime? date = dpDateSelection.SelectedDate;
logDate = date != null ? date.Value.ToString("yyyy-MM-dd") : null;
dpDateSelection.ToolTip = logDate;
LoadLogs(logDate);
}
private void LoadLogs(string ldate)
{
string[] logs = Directory.GetFiles(logPath + ldate, "*.ininlog");
InitializeComponent();
logList = new ObservableCollection<String>();
logList.Clear();
foreach (string logName in logs)
{
string s = logName.Substring(logName.IndexOf(ldate) + ldate.Length + 1);
int extPos = s.LastIndexOf(".");
s = s.Substring(0, extPos);
logList.Add(s);
}
this.DataContext = this;
}
<ListBox x:Name="Logs" ItemsSource="{Binding logList}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" ToolTip="{Binding}" Tag="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Upvotes: 0
Views: 273
Reputation: 61349
You will want to start by using an ItemsControl instead of a StackPanel, since ItemsControls are automatically set up to display collections of things:
<ItemsControl ItemsSource="{Binding Logs}"/>
Note the use of ItemsSource
. With the accompanying binding string, it basically says "Look for a property on the DataContext called "Logs" and put everything in it into this control".
Next you said you wanted this displayed as checkboxes, so we use an item template:
<ItemsControl ItemsSource="{Binding Logs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content={Binding .}/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This says "Use a checkbox for each Item in the ItemsSource". The DataTemplate can be a Grid or other collection control as well, so this is a really powerful feature in WPF. The "Binding ." just binds to the object itself (a string in this case, so we don't need a special path).
Finally, you need to set up a property to bind to in your view model:
ObservableCollection<String> Logs {get; set;}
You want an ObservableCollection so that when anything is added to or removed from the list, it automatically updates the UI. If you are going to be completely replacing the list (assignment), then you need to implement INotifyPropertyChanged
and invoke the PropertyChanged event in that properties setter.
In your posted loop, you would add each log file to this property.
Also, make sure that somewhere you set the DataContext property of the XAML file (View) to your view model object. If everything is in code behind, use DataContext = this
. Note that doing this is considered bad practice, and you should use a separate class (ViewModel).
You didn't mention what you wanted the CheckBoxes to do, so I haven't included anything related to that in my answer. You will likely want to abstract your logs into an object with a "Selected" property you can then bind the IsChecked
property of the CheckBoxes to.
Obviously this is a lot to take in, please let me know if I can clarify anything or help further!
Update You put the property in your ViewModel (DataContext). Whatever class that is, you write:
ObservableCollection<String> Logs {get; set;}
private void LoadLogs()
{
string[] logs = Directory.GetFiles(logPath + logDate, "*.ininlog");
foreach(string logName in logs)
{
string s = logName.Substring(logName.IndexOf(logDate) + logDate.Length + 1);
int extPos = s.LastIndexOf(".");
s = s.Substring(0, extPos);
//MessageBox.Show(s);
Logs.Add(s); //Add the parsed file name to the list
}
}
Upvotes: 4