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