我们如何访问Itemtemplate Silverlight中的控件

时间:2010-02-15 21:22:24

标签: silverlight listbox

我有一个列表框。我有一个带有堆栈面板的项目模板。 它有一个文本框和项目模板中的复选框。

有没有办法可以访问复选框并在选定的索引更改后启用/禁用它?

<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}" />

2 个答案:

答案 0 :(得分:2)

确定您的ItemsSource已绑定:

<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" />

您实际上不需要更改CheckBox.IsChecked属性,而是更改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
}

如果您查看按钮上的Click事件的事件处理程序,您可以看到我所做的只是获取项目并更改了值。这会立即反映在用户界面上。

更新:我发现这不是你要求的。以下是一些想法:

您可以为复选框设置事件处理程序:

<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>

获取后面代码的参考:

private void CheckBox_Click(object sender, RoutedEventArgs e)
{
    CheckBox chk = sender as CheckBox;
    chk.IsEnabled = false;
}

当然,问题在于,如果您禁用该复选框,则会失去对Click envent的访问权限。

另一种选择是使用VisualTreeHelper在ListBox上的选择更改时获取对CheckBox的引用:

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);
        }
    }
}

这当然不是性能的最佳选择,但您可以获得更大的灵活性。

答案 1 :(得分:0)

以下是使用RadioButtons的解决方案:
http://leeontech.wordpress.com/2009/03/18/creating-radiobuttonlist/

将其更改为复选框应该很容易。

相关问题