[英]How to set focus to a bound ListboxItem by pressing its child element?
I am developping a small WPF application which consist mostly in displaying ObservableCollection<>
in others ObservableCollection<>
, and so on. 我该深化发展主要由在显示一个小WPF应用程序ObservableCollection<>
在别人ObservableCollection<>
等等。
Here is a code example of what my application looks like: 这是我的应用程序外观的代码示例:
<Listbox Name="MainList" ItemsSource={Binding}>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Textblock Text={Binding MainName} />
<Button>Add item</Button>
<Button>Delete item</Button>
<Listbox Name="ChildList" ItemsSource="{Binding Path=ChildItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<Textblock Text={Binding ChildName} />
</DataTemplate>
</ListBox.ItemTemplate>
</Listbox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</Listbox>
And visually it pretty much looks like this: 从视觉上看,它看起来像这样:
EDIT: 编辑:
I will re-explain what I am trying to do. 我将重新解释我要做什么。
Whenever I click Button A
or Button B
I want to Select the MainList
ListBoxItem
in which they are contained (ie: A Item
) 每当我单击Button A
或Button B
我都想选择包含它们的MainList
ListBoxItem
(即: A Item
)
And in a second time whenever I click Button B
: 第二次,每当我单击Button B
:
ListBoxItem
is selected in ChildList
(Second Listbox in the picture) 我想确保在ChildList
选择了一个ListBoxItem
(图片中的第二个Listbox) But my main problem is since everything is generated by my bindings I cannot get, so far, an element from my ChildList
because ChildList
is duplicated in any of my MainList
ListBoxItem
. 但是我的主要问题是,由于一切都是由绑定生成的,所以到目前为止,我ChildList
从ChildList
获得一个元素,因为ChildList
在任何MainList
ListBoxItem
都是重复的。
If I understand well the problem is that you want first click on a button of unselected item to select the MainItem
, and on next click, when MainItem
is already selected, preform click action. 如果我对问题的理解很好,那就是您希望首先单击未选择项目的按钮以选择MainItem
,然后在下次单击时(已经选择MainItem
时) MainItem
单击操作。 Try this when button is clicked: 单击按钮时请尝试以下操作:
private ListBoxItem FindItemContainer(DependencyObject obj)
{
while (obj != null && !(obj is ListBoxItem))
{
obj = VisualTreeHelper.GetParent(obj);
}
if (obj != null)
return obj as ListBoxItem;
else
return null;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var lbi = FindItemContainer(sender as DependencyObject);
if (lbi != null)
{
if (lbi.IsSelected)
{
//do click event
}
else
lbi.IsSelected = true;
}
}
Of course you can also do it more MVVM way by binding ListBoxItem.IsSelected
to lets say bool MainItem.MyItemIsSelected
当然,您也可以通过将ListBoxItem.IsSelected
绑定为bool MainItem.MyItemIsSelected
来执行更多MVVM方法
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Path=MyItemIsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
and Button.Command
to your ICommand MainItem.DeleteCommand
and then when command is executed do something like that: 和Button.Command
到ICommand MainItem.DeleteCommand
,然后在执行命令时执行以下操作:
if (MyItemIsSelected)
{
//do command body
}
else
MyItemIsSelected = true;
which will be better long term because you could replicate SelectedItem
behaviour in ChildList
object (add MyItemIsSelected
and bind it to inner 'ListBoxItem.IsSelected
, like discribed above) and add MySelectedItem
property to ChildList
: 从长远来看这会更好,因为您可以在ChildList
对象中复制SelectedItem
行为(添加MyItemIsSelected
并将其绑定到内部的'ListBoxItem.IsSelected
,如上文所述),然后将MySelectedItem
属性添加到ChildList
:
ChildItem MySelectedItem
{
get
{
return Items.FirstOrDefault(n=>n.MyItemIsSelected);
}
}
and your delete command would look like this: 您的删除命令将如下所示:
if (MyItemIsSelected)
{
ChildItem selItem = ChildItems.MySelectedItem;
if (selItem != null) ChildItems.Items.Remove(selItem);
}
else
MyItemIsSelected = true;
if everything is data bound and lists are ObservableCollections
then you can do all that in object and UI will follow. 如果所有内容都是数据绑定的,并且列表是ObservableCollections
则可以在object和UI中进行所有操作。 Actually you can do only this child selection binding bit and still use first solution and in Button_Click
look like this: 实际上,您只能执行此子选择绑定位,并且仍然使用第一个解决方案,并且在Button_Click
如下所示:
private void Button_Click(object sender, RoutedEventArgs e)
{
var lbi = FindItemContainer(sender as DependencyObject);
if (lbi != null)
{
if (lbi.IsSelected)
{
MainItem mainItem = lbi.Content as MainItem;
ChildItem selChild = mainItem.ChildItems.MySelectedItem;
if (selChild != null) mainItem.ChildItems.Items.Remove(selChild);
}
else
lbi.IsSelected = true;
}
}
Here is simple, working example on Dropbox 这是Dropbox上的简单工作示例
You can do everything you want to do in code behind: 您可以在后面的代码中做所有想做的事情:
Find the selected item in second listbox: locating the ListBox in the DataTemplate is tricky, but you could set its IsSynchronizedWithCurrentItem property to True, and then use the underlying child collection's default CollectionView. 在第二个列表框中找到选定的项目:在DataTemplate中定位列表框很棘手,但是您可以将其IsSynchronizedWithCurrentItem属性设置为True,然后使用基础子集合的默认CollectionView。 You'd find the current item of MainList like above. 您会发现上面的MainList的当前项目。 Then you'd use: 然后,您将使用:
itemToDelete = CollectionViewSource.GetDefaultView(item.ChildItems).CurrentItem; item.ChildItems.Remove(itemToDelete);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.