Assming you have your ItemsSource binded:
<ListBox x:Name="myList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Check, Mode=TwoWay}" />
<TextBlock Text="{Binding Name, Mode=TwoWay}"
Width="100" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="button1"
Content="Uncheck 2"
Click="button1_Click" />
You don't actually need to change the CheckBox.IsChecked property, but the value on your ItemsSource:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
myList.ItemsSource = ListInfo.getInfo();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
ListInfo item = myList.Items[1] as ListInfo;
item.Check = !item.Check;
}
}
public class ListInfo : INotifyPropertyChanged
{
private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
NotifyPropertyChange("Name");
}
}
private bool check;
public bool Check
{
get
{
return check;
}
set
{
check = value;
NotifyPropertyChange("Check");
}
}
public static ObservableCollection<ListInfo> getInfo()
{
ObservableCollection<ListInfo> data = new ObservableCollection<ListInfo>();
data.Add(new ListInfo { Name = "Some text 1", Check = true });
data.Add(new ListInfo { Name = "Some text 2", Check = false });
data.Add(new ListInfo { Name = "Some text 3", Check = true });
return data;
}
public void NotifyPropertyChange(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
If you take a look at the event handler for the Click event on the button, you can see that all I did was get the item and changed the value. This immediately reflects on the UI.
UPDATE: I see that this was not what you asked for. Here are a couple of ideas:
You can have an event handler for your check box:
<ListBox x:Name="myList">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Check, Mode=TwoWay}"
IsEnabled="True"
Content="{Binding Name, Mode=TwoWay}"
Click="CheckBox_Click" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And get the reference on the code behind:
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox chk = sender as CheckBox;
chk.IsEnabled = false;
}
Of course the problem here is that if you disable the checkbox you lose access to the Click envent.
Another choice is to use the VisualTreeHelper to get reference to your CheckBox when the selection change on the ListBox:
private void myList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox list = sender as ListBox;
ListInfo current = list.SelectedItem as ListInfo;
List<CheckBox> checkBoxes = new List<CheckBox>();
getCheckBoxes(list, ref checkBoxes);
foreach (CheckBox checkBox in checkBoxes)
{
if (checkBox.Content.ToString() == current.Name)
{
checkBox.Foreground = new SolidColorBrush(Colors.Red);
}
}
}
public void getCheckBoxes(UIElement parent, ref List<CheckBox> items)
{
int count = VisualTreeHelper.GetChildrenCount(parent);
if (count > 0)
{
for (int i = 0; i < count; i++)
{
UIElement child = VisualTreeHelper.GetChild(parent, i) as UIElement;
if (child.GetType() == typeof(CheckBox))
{
items.Add(child as CheckBox);
}
getCheckBoxes(child, ref items);
}
}
}
This of course is not the best option for performance but you get more flexibility.