Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Silverlight中获取xaml.cs中复选框的内容_Xaml_Silverlight - Fatal编程技术网

在Silverlight中获取xaml.cs中复选框的内容

在Silverlight中获取xaml.cs中复选框的内容,xaml,silverlight,Xaml,Silverlight,我是silverlight的新手。我正在尝试生成一个复选框列表(包含内容)。这个想法是,用户将选择其中一些复选框并按下按钮。然后,我们尝试读取所选复选框的内容以进行进一步处理。我不知道会有多少个复选框,因此我不能使用绑定。 这是.xaml文件中的代码段 <StackPanel Grid.Row="21" Grid.Column="1" Margin="5" VerticalAlignment="Center"> <Grid> <Grid.Co

我是silverlight的新手。我正在尝试生成一个复选框列表(包含内容)。这个想法是,用户将选择其中一些复选框并按下按钮。然后,我们尝试读取所选复选框的内容以进行进一步处理。我不知道会有多少个复选框,因此我不能使用绑定。 这是.xaml文件中的代码段

<StackPanel Grid.Row="21" Grid.Column="1" Margin="5" VerticalAlignment="Center">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <ItemsControl Name="infoPairItems" ItemsSource="{Binding InfoPair}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <CheckBox Grid.Column="0" Name="infoPairSelectBox" IsEnabled="True" IsThreeState="False" 
                        Margin="0,5" FontSize="12" IsChecked="bool"
                        Content="{Binding Converter={StaticResource infoPairToStringValueConverter}}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</StackPanel>
即使选中了部分复选框,所有复选框的日志“checkbox value false”也始终会打印出来。我试图使用调试器。看起来变量容器正在加载正确的值。要么LoadContent()方法不起作用,要么我使用了错误的方法。
如果这是一个重复的问题,我事先道歉。我试图研究stackoverflow之前的问题,但找不到任何答案。请指导我正确的方向。

我将解释发生了什么以及如何解决:

1.-您得到的是datatemplate,而不是datatemplate的实例,如果您想管理实例,可以使用Loaded事件向列表中添加项目,以创建和更新例如列表

2.-如果您创建以下内容,那么使所有这些事件成为一个非常复杂的代码来管理就更容易了:

<CheckBox Grid.Column="0" 
          Name="infoPairSelectBox" 
          IsEnabled="True" 
          IsThreeState="False" 
          Margin="0,5" 
          FontSize="12" 
          IsChecked="{Binding Selected, Mode=TwoWay}" 
          Content="{Binding Info}"/>
2.1例如,一个类具有一个bool和一个字符串,用于INotifyPropertyChanged的内容:

public class InfoSelection : Model
{
 Property bool for Selected 
 Property string for Info, or whatever and the converter
}
2.2在DataContext中包含该类类型所需项的列表

public List<InfoSelection> {get;set;}
公共列表{get;set;}
(例如,如果在构造函数中只初始化一次,则不需要实现InotiPropertyChanged,只需清除或移除项,而不需要重新分配)

2.3在Xaml绑定中,更改为以下内容:

<CheckBox Grid.Column="0" 
          Name="infoPairSelectBox" 
          IsEnabled="True" 
          IsThreeState="False" 
          Margin="0,5" 
          FontSize="12" 
          IsChecked="{Binding Selected, Mode=TwoWay}" 
          Content="{Binding Info}"/>

我不知道会有多少个复选框,因此我不能使用绑定

不对

为了直观地显示两级数据,可以对父项及其子项使用带有单个数据模板的
ItemsControl

然后,为了允许编辑(您的删除操作),需要从子节点中识别父节点是谁,并获取复选框的状态

该标识要求我们将初始数据投影到包装类中,以便于绑定/标识

让我解释一下


假设我们的数据显示顶级姓氏以及与姓氏相关的所有名字

上面模拟了从数据库检索的以下数据类的顶级复选框(删除全部)和子复选框(删除单个项):

public class VectorStrings
{
    public int          Id         { get; set; }
    public string       LastName   { get; set; }
    public List<string> FirstNames { get; set; }
}
好极了!现在我们只需要嵌套的
ItemControl
类来显示数据:

<ItemsControl  ItemsSource="{Binding CheckBoxData}">
    <ItemsControl.Resources>
        <system:String x:Key="Format">Delete All for ID: '{0}' </system:String>
    </ItemsControl.Resources>
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Vertical" Margin="10" />
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
    <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="6,0,0,0">
                <CheckBox Tag="{Binding Id}" Margin="0,0,0,10"  Click="DeleteAll_Click">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Id, StringFormat={StaticResource Format}}"/>
                        <TextBlock Text="{Binding DisplayName}" Margin="4,0,6,0"/>
                        <ItemsControl ItemsSource="{Binding Children}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <CheckBox Tag="{Binding Tag}" 
                                              Content="{Binding DisplayName}" 
                                              Click="DeleteIndividual_Click"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </CheckBox>
            </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>
子点击

因此,我已经确定了复选框状态以及目标原始项。这段代码最终模拟了您想要做的事情。我将可观察集合的实际管道留给您来移除项目。但这让人明白了这一点


我建议您先在WPF中进行试验,然后再将其带到Silverlight,因为概念是一样的,但在WPF中进行试验更容易/更快。

我不同意您的假设,即由于数据的锯齿特性,您不能使用绑定。如果可以绑定,请提供要显示的控件的XAML示例,并提供要绑定到的数据示例,这可能就是答案。InfoPair是对象的ObservableCollection,每个对象包含2个字符串。转换器只是将它们用逗号分隔成单个字符串。它们只是我正在介绍的一些信息实体。然后,当我按下按钮时,我会调用后端来删除这些实体。
public class VectorCheckbox
{
    public int                  Id          { get; set; }
    public int                  ParentId    { get; set; }
    public string               DisplayName { get; set; }
    public List<VectorCheckbox> Children    { get; set; }
    public object Tag { get; set; } // Same concept as a visual control property 'Tag'
}
CheckBoxData = 
    LastNames.Select(ln => new VectorCheckbox()
           {
               DisplayName = ln.LastName,
               Id = ln.Id,
               Tag = ln,
               Children = ln.FirstNames.Select((fn, index) => new VectorCheckbox()
               {
                   Id          = index,
                   ParentId    = ln.Id,
                   DisplayName = fn,
                   Tag         = ln.Id // Hold the parent Id for identification
               }).ToList()

         })
            .ToList();
<ItemsControl  ItemsSource="{Binding CheckBoxData}">
    <ItemsControl.Resources>
        <system:String x:Key="Format">Delete All for ID: '{0}' </system:String>
    </ItemsControl.Resources>
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Vertical" Margin="10" />
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
    <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="6,0,0,0">
                <CheckBox Tag="{Binding Id}" Margin="0,0,0,10"  Click="DeleteAll_Click">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Id, StringFormat={StaticResource Format}}"/>
                        <TextBlock Text="{Binding DisplayName}" Margin="4,0,6,0"/>
                        <ItemsControl ItemsSource="{Binding Children}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <CheckBox Tag="{Binding Tag}" 
                                              Content="{Binding DisplayName}" 
                                              Click="DeleteIndividual_Click"/>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </StackPanel>
                </CheckBox>
            </StackPanel>
    </DataTemplate>
</ItemsControl.ItemTemplate>
private void DeleteAll_Click(object sender, RoutedEventArgs e)
{
    var cb = sender as CheckBox;

    if (cb != null)
    {
        var id = (int)cb.Tag;

        var nameInstance = ViewModel.LastNames.FirstOrDefault(nm => nm.Id == id);

        if (nameInstance != null)
            MessageBox.Show(string.Format("Delete all for {0} of names {1} (Status {2})",
            nameInstance.LastName,
            string.Join(",", nameInstance.FirstNames),
            ((cb.IsChecked ?? false) ? "Checked" : "UnChecked")
            ));
    }
}
private void DeleteIndividual_Click(object sender, RoutedEventArgs e)
{
    var cb = sender as CheckBox;

    if (cb != null)
    {
        var parentId = (int)cb.Tag; // Parent Id

        var nameInstance = ViewModel.LastNames.FirstOrDefault(nm => nm.Id == parentId);

        if (nameInstance != null)
            MessageBox.Show(string.Format("Delete individual for {0} of name {1} (Status {2})",
            nameInstance.LastName,
            cb.Content,
            ((cb.IsChecked ?? false) ? "Checked" : "UnChecked")
            ));

    }
}