views:

519

answers:

2

i have a list box. i have an item template with a stack panel in it. it has a text box and a check box in the item template.

is there a way i can access the check box and enable/disable it on selected index changed?

<UserControl.Resources> <DataTemplate x:Key="UserApplicationsTemplate"> <StackPanel Orientation="Horizontal" Margin="2" ToolTipService.Placement="Mouse" ToolTipService.ToolTip="{Binding Description, Mode=OneWay}"> <TextBlock Text="{Binding Mode=OneWay}" TextWrapping="Wrap" Width="100" DataContext="{Binding ApplicationName, Mode=OneWay}" /> <CheckBox x:Name="{Binding ApplicationName, Mode=OneWay}" Margin="5,0,0,0" Click="IsActive_Clicked" IsChecked="{Binding IsActive, Mode=OneWay}" Content="IsActive"/> </StackPanel> </DataTemplate> </UserControl.Resources>

<ListBox x:Name="lstbxUserApplications" Height="357" ItemsSource="{Binding Mode=OneWay}" SelectionMode="Single" ItemTemplate="{StaticResource UserApplicationsTemplate}" />

A: 

Here is a solution using RadioButtons:
http://leeontech.wordpress.com/2009/03/18/creating-radiobuttonlist/

It should be easy enough to change it to checkboxes.

Henrik Söderlund
i am trying to access the container of the listboxitem in code behind.i have a listbox with an item template. the item template has a stack panel and in that it has a text box and a check box.i am trying to access the check box on certain logic in the code behind and disabling it.i want the get access to the control for me to be able to do, chkbox.IsEnabled = false
gkopparam
+1  A: 

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.

Arturo Molina
i am trying to access the UI property to enable/disable the check box. i do not have a problem setting the VALUE of the check box.like if i want to change the background color or some other property of the container of the listboxitem, i want to be able to do this in code behind.
gkopparam
Sorry about that! I updated the answer, I hope that actually helps, if not, let me know.
Arturo Molina
i tried using thisUIElement child = VisualTreeHelper.GetChild(parent, i) as UIElement;but it is not giving me the child, is it because i am using a static resource for the listbox item itemtemplate?it does not give me enough space to put the XAML here. i will try to update the original post with the XAML
gkopparam
From what I'm seeing in your XAML, you're trying the CheckBox.Click approach right? I was suggesting to use VisualTreeHelper with the SelectionChanged event on the ListBox. If you use the CheckBox.Click event, you can get the CheckBox reference with just this code: CheckBox chk = sender as CheckBox;
Arturo Molina
actually the .click event does another action. i DO NOT have .getchild there.buti am trying to enable/disable some check boxes depending on certain logic of other parts in the page.
gkopparam
Hi Arturo, i am still stuck with the issue. any other way to get around the problem?
gkopparam
No, the use of the itemtemplate as a StaticResource should not be an issue. One thing you should know is that the position of a Child at runtime is not exactly as defined in your XAML. I would recommend using a tool such as SilverlightSpy (you can download a trial) then you can see the VisualTree structure or your app in RunTime.
Arturo Molina
I did write a post about this after I answered your question. It's in spanish, but you can checkout the code (my blog has Bing Translator, but the translation is not perfect): http://jamolina.com/index.php/2010/02/recorriendo-elementos-del-visualtree/
Arturo Molina
i will try SS . thanks
gkopparam