2

I'm getting an error where chkBox1 does not exist in the current context, anyone has a solution to this?

Here is the XAML:

 <ListBox ItemsSource="{Binding Files}" Margin="0,42,0,115" Name="lstBox1">
                <ListBox.ItemTemplate>
                    <DataTemplate >
                        <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="{Binding FileName}" Name="chkBox1" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Here is the code that has the chkBox1 in it:

private void button2_Click(object sender, RoutedEventArgs e)
        {
            ViewDiskModel model = this.ContentPanel.DataContext as ViewDiskModel;


            if (chkBox1.IsChecked == true)
            {
                model.DeleteSelectedFiles.Execute(null);


                MessageBox.Show("Files Successfully Deleted.");
            }
            else
            {
                MessageBox.Show("Please select a file to delete.");
            }

        }
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
lala
  • 149
  • 2
  • 13

3 Answers3

2

If there are many Files there will be many check boxes. How would you distinguish between these when you specify a single name?

Do not refer to the View (control) in the ViewModel. Replace the string collection (filename collection) with a collection of File. Make sure the File class has two properties: Name and IsSelected.

Then bind the content of the check box to the Name and the IsChecked Property to the IsSelected property.

That way you only have to check the IsSelected property in the ViewMODEL, not in the view.

Suggestion

    class File : INotifyPropertyChanged  //  implementation not added
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                if(_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        private boolean _isSelected;
        public boolean IsSelected
        {
            get { return _isSelected; }
            set
            {
                if(_isSelected != value)
                {
                    _isSelected = value;
                    OnPropertyChanged("IsSelected");
                }
            }
        }
    }

    class ViewDiskModel : INotifyPropertyChanged // implementation missing
    {
        private ObservableCollection<File> _files;

        public ObservableCollection<File> Files
        {
            get
            {
                return _files;
            }
set
            {
                if(_files != value)
                {
                    _files = value;
                    OnPropertyChanged("Files");
                }
            }
        }
    } 

XAML:

<ListBox ItemsSource="{Binding Files}" Margin="0,42,0,115" Name="lstBox1">
    <ListBox.ItemTemplate>
        <DataTemplate >
            <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}"
                      Content="{Binding FileName}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>  

Then:

private void Button2_Click(object sender, RoutedEventArgs e)
{
    ViewDiskModel model = this.ContentPanel.DataContext as ViewDiskModel;

    if(model.Files.Any(file => file.IsSelected))
    {
        model.DeleteSelectedFiles.Execute(null);
        MessageBox.Show("Files Successfully Deleted.");
    }
    else
    {
        MessageBox.Show("Please select files to delete.");
    }
}
lala
  • 149
  • 2
  • 13
Emond
  • 50,210
  • 11
  • 84
  • 115
  • your idea is great, but i'm not sure where to change. – lala Jul 04 '11 at 14:39
  • Please post the code of the ViewDiskModel class and I will make an example. – Emond Jul 04 '11 at 14:43
  • I have Edited my question and added the ViewDiskModel class. – lala Jul 04 '11 at 14:52
  • So, am i to replace that files property over my current files and my loadfiles? – lala Jul 04 '11 at 15:20
  • and am i to remove the IsChecked Property? – lala Jul 04 '11 at 15:26
  • I'm not sure whether i've edited the way that you've suggested. I've edited my ViewDiskModel Class on my question. Feel free to check when you are free – lala Jul 04 '11 at 16:15
  • No, don't remove the IsChecked. I made up my own names/properties. Your code looks fine my guess is that all you need to do is use this line: `if(model.Files.Any(file => file.IsSelected))` instead of accessing the controls. – Emond Jul 04 '11 at 16:56
  • No errors, but after i've save the file, there's nothing on my load page. Will get back to you after a night's rest. – lala Jul 04 '11 at 17:34
  • Please show us the code where you are assigning the ViewModel to the DataContext of the View – Emond Jul 04 '11 at 17:46
  • DUDE, I've finally fixed it, and now it works like a charm! Thanks a lot! All i need was the Button codes that you've suggested to me! – lala Jul 05 '11 at 02:43
  • To make it 'true'-MVVM you could replace the button click event by a command on the ViewModel and bind the Command property of the button. – Emond Jul 05 '11 at 04:31
0

If checkbox is inside the listbox you can not access it directly. you have to do it like that:

CheckBox chkBox1 = (CheckBox)lstBox1.Controls[index_of_the_list_item].FindControl("chkBox1");

Only then you can operate using that checkbox:

if(chkBox1.checked ){}

You have to use ID to find a control though, not it's name. And somehow you need to know what index of the list you want to check...

Daniel Gruszczyk
  • 5,379
  • 8
  • 47
  • 86
  • Now i'm receiving an error where [index_of_the_list_item] does not exist in the current context. – lala Jul 04 '11 at 14:27
0

DataTemplate controls are not available by name in code behind, because they are not members of your Window or Page (or whatever else) class. This article has a solution. Basically, subscribe to the Loaded event of the control you want, and in the code behind, save the event's sender parameter, which is the control in question.