Silverlight如何在使用datatemplates中的按钮时提升listbox的选定项
在Listbox控件中,我有一个由文本和按钮组成的数据模板。鉴于Silverlight/WPF的性质,当我单击listbox项中的按钮时,按钮事件在选择listbox项之前被捕获。因此,如果我试图传递所选列表框项目的记录ID,我当前只能通过先单击并选择列表框项目,然后单击按钮来传递 是否有办法提升listbox项目的选择,以便在创建listbox项目时,我能够单击listbox项目内的按钮,并调用一些事件(selectionChanged?),允许我捕获所选记录id并将其用于某些其他操作(在方法中作为参数传递等)。我正在使用Simple MVVM toolkit进行此实现,因此我想知道是否可以在viewModel中处理此问题,或者是否需要在后面的控件代码中处理此问题,然后将选择推送到viewModel listbox控件显示为:Silverlight如何在使用datatemplates中的按钮时提升listbox的选定项,silverlight,mvvm,listbox,datatemplate,Silverlight,Mvvm,Listbox,Datatemplate,在Listbox控件中,我有一个由文本和按钮组成的数据模板。鉴于Silverlight/WPF的性质,当我单击listbox项中的按钮时,按钮事件在选择listbox项之前被捕获。因此,如果我试图传递所选列表框项目的记录ID,我当前只能通过先单击并选择列表框项目,然后单击按钮来传递 是否有办法提升listbox项目的选择,以便在创建listbox项目时,我能够单击listbox项目内的按钮,并调用一些事件(selectionChanged?),允许我捕获所选记录id并将其用于某些其他操作(在方法
<ListBox x:Name="ResultListBox"
HorizontalAlignment="Stretch"
Background="{x:Null}"
Grid.Row="1"
BorderThickness="0" HorizontalContentAlignment="Stretch"
ItemContainerStyle="{StaticResource ListBoxItemStyle1}"
ItemsSource="{Binding SearchResults[0].Results}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Style="{StaticResource ListBoxStyle1}">
<ListBox.ItemTemplate>
<DataTemplate>
<dts:TypeTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch">
<!-- Template 1 -->
<formatter:TypeTemplateSelector.CFSTemplate>
<DataTemplate>
<qr:ucIndex_Product />
</DataTemplate>
</formatter:TypeTemplateSelector.CFSTemplate>
<!-- Template 2 -->
<formatter:TypeTemplateSelector.PersonTemplate>
<DataTemplate>
<qr:ucIndex_Person />
</DataTemplate>
</formatter:TypeTemplateSelector.PersonTemplate>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
在datatemplate(用户控件)中,按钮与许多其他字段一起驻留。除非有人要求,否则我将暂时省略该代码
提前谢谢 将其放入您的
列表框中。参考资料
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>
您也可以使用下面的代码,它不使用代码隐藏,但是只要ListBoxItem具有键盘焦点,它就会保持选中状态。焦点离开后,该项目将被取消选中
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
编辑
由于Silverlight没有EventSetter,因此可以使用ListBox的已加载事件,并将以下内容添加到代码中:
private void ResultListBox_Loaded(object sender, RoutedEventArgs e)
{
ListBox list = (ListBox)sender;
list.GotFocus += ResultListBox_GotFocus;
}
void ResultListBox_GotFocus(object sender, RoutedEventArgs e)
{
var item = FindAncester<ListBoxItem>((DependencyObject)e.OriginalSource);
if (item != null) item.IsSelected = true;
}
T FindAncester<T>(DependencyObject current)
where T : DependencyObject
{
current = VisualTreeHelper.GetParent(current);
while (current != null)
{
if (current is T)
{
return (T)current;
}
current = VisualTreeHelper.GetParent(current);
};
return null;
}
private void ResultListBox\u已加载(对象发送方、路由目标方)
{
列表框列表=(列表框)发送方;
list.GotFocus+=ResultListBox\u GotFocus;
}
void ResultListBox\u GotFocus(对象发送方,路由目标)
{
var项=FindAncester((DependencyObject)e.OriginalSource);
如果(item!=null)item.IsSelected=true;
}
T FindAncester(依赖对象当前)
其中T:DependencyObject
{
当前=VisualTreeHelper.GetParent(当前);
while(当前!=null)
{
如果(电流为T)
{
返回(T)电流;
}
当前=VisualTreeHelper.GetParent(当前);
};
返回null;
}
这将捕获列表框的焦点事件,获取触发焦点事件的控件,并向上遍历可视化树以查找ListBoxItem
对象,并将其选定值设置为true。将其放入列表框。参考资料
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
</Style>
您也可以使用下面的代码,它不使用代码隐藏,但是只要ListBoxItem具有键盘焦点,它就会保持选中状态。焦点离开后,该项目将被取消选中
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
编辑
由于Silverlight没有EventSetter,因此可以使用ListBox的已加载事件,并将以下内容添加到代码中:
private void ResultListBox_Loaded(object sender, RoutedEventArgs e)
{
ListBox list = (ListBox)sender;
list.GotFocus += ResultListBox_GotFocus;
}
void ResultListBox_GotFocus(object sender, RoutedEventArgs e)
{
var item = FindAncester<ListBoxItem>((DependencyObject)e.OriginalSource);
if (item != null) item.IsSelected = true;
}
T FindAncester<T>(DependencyObject current)
where T : DependencyObject
{
current = VisualTreeHelper.GetParent(current);
while (current != null)
{
if (current is T)
{
return (T)current;
}
current = VisualTreeHelper.GetParent(current);
};
return null;
}
private void ResultListBox\u已加载(对象发送方、路由目标方)
{
列表框列表=(列表框)发送方;
list.GotFocus+=ResultListBox\u GotFocus;
}
void ResultListBox\u GotFocus(对象发送方,路由目标)
{
var项=FindAncester((DependencyObject)e.OriginalSource);
如果(item!=null)item.IsSelected=true;
}
T FindAncester(依赖对象当前)
其中T:DependencyObject
{
当前=VisualTreeHelper.GetParent(当前);
while(当前!=null)
{
如果(电流为T)
{
返回(T)电流;
}
当前=VisualTreeHelper.GetParent(当前);
};
返回null;
}
这将捕获ListBox的焦点事件,获取触发焦点事件的控件,并向上遍历可视化树以查找ListBoxItem
对象,并将其选定值设置为true。Rachel的解决方案非常有效。我在这种方法中发现的一个问题是,它确实将全部注意力放在所选项目上。因此,用户需要在控件内双击以将焦点放在其他项目上,例如可选文本或其他按钮。在进一步处理这个问题之后,我发现您还可以通过将listbox所选项目设置为您正在单击的对象的数据上下文等来解决此问题。这很好地工作,并允许您将其设置为控件中的任何UI对象
ListBox.SelectedItem = ((HyperlinkButton)sender).DataContext;
在本例中,我在数据模板中使用了超链接按钮。单击它们会将焦点设置为选定的列表框项目 Rachel的解决方案非常有效。我在这种方法中发现的一个问题是,它确实将全部注意力放在所选项目上。因此,用户需要在控件内双击以将焦点放在其他项目上,例如可选文本或其他按钮。在进一步处理这个问题之后,我发现您还可以通过将listbox所选项目设置为您正在单击的对象的数据上下文等来解决此问题。这很好地工作,并允许您将其设置为控件中的任何UI对象
ListBox.SelectedItem = ((HyperlinkButton)sender).DataContext;
在本例中,我在数据模板中使用了超链接按钮。单击它们会将焦点设置为选定的列表框项目 rlcrows做对了!使用数据上下文:
ObservableCollection<Employee> employees1;
...
listBox1.ItemsSource = employees1;
...
//DataTemplate in ListBox has a button with following event
private void bnPromoteEmployee_Click(object sender, RoutedEventArgs e)
{
Employee emp1 = (Employee)((Button)sender).DataContext;
emp1.Promote();
}
observedcollection员工1;
...
listBox1.ItemsSource=员工1;
...
//ListBox中的DataTemplate有一个包含以下事件的按钮
私有无效BNPromoteTemployee_单击(对象发件人,路由收件人)