Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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
C# 如何通过按下绑定ListboxItem的子元素来设置其焦点?_C#_Wpf_Xaml_Data Binding_Listboxitem - Fatal编程技术网

C# 如何通过按下绑定ListboxItem的子元素来设置其焦点?

C# 如何通过按下绑定ListboxItem的子元素来设置其焦点?,c#,wpf,xaml,data-binding,listboxitem,C#,Wpf,Xaml,Data Binding,Listboxitem,我正在开发一个小的WPF应用程序,主要包括在其他ObservableCollection中显示ObservableCollection,等等 下面是我的应用程序的代码示例: 添加项 删除项目 从视觉上看,它几乎像这样: if (MyItemIsSelected) { ChildItem selItem = ChildItems.MySelectedItem; if (selItem != null) ChildItems.Items.Remove(selItem); } el

我正在开发一个小的WPF应用程序,主要包括在其他
ObservableCollection
中显示
ObservableCollection
,等等

下面是我的应用程序的代码示例:


添加项
删除项目
从视觉上看,它几乎像这样:

if (MyItemIsSelected)
{
    ChildItem selItem = ChildItems.MySelectedItem;
    if (selItem != null) ChildItems.Items.Remove(selItem);
}
else
    MyItemIsSelected = true;
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;
   }
}

编辑:

我会重新解释我想做什么

  • 每当我单击
    按钮A
    按钮B
    时,我都希望选择包含它们的
    主列表
    列表框项目
    (即:
    项目

  • 第二次,每当我点击
    按钮B

    • 我想确保在
      ChildList
      中选择了
      ListBoxItem
      (图片中的第二个列表框)
    • 如果是这样,我想在代码隐藏中删除它

但我的主要问题是,由于所有内容都是由绑定生成的,因此我无法从我的
ChildList
中获取元素,因为
ChildList
在我的
MainList
ListBoxItem
中重复了
ChildList
,您可以在代码隐藏中执行您想要执行的所有操作:

  • 查找按下按钮的项目:在click事件中,将sender参数强制转换为type Button。其DataContext属性将包含要选择的项
  • 选择项目:将MainList.SelectedItem设置为该项目
  • 焦点将放在按钮上,但这应该没问题,因为它位于项目内部
  • 在第二个列表框中查找所选项目:在DataTemplate中查找列表框很棘手,但是可以将其IsSynchronizedWithCurrentItem属性设置为True,然后使用基础子集合的默认CollectionView。您可以找到MainList的当前项,如上面所示。然后你会使用:

    itemToDelete=CollectionViewSource.GetDefaultView(item.ChildItems).CurrentItem;
    item.ChildItems.Remove(itemToDelete)


如果我理解得很清楚,问题是您希望首先单击未选择项的按钮以选择
main项
,然后在下一次单击时,当已选择
main项
时,执行单击操作。单击此按钮时尝试此操作:

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;
   }
}
当然,您也可以通过将
ListBoxItem.IsSelected
绑定到
boolmainitem.myitemselected

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
        <Setter Property="IsSelected" Value="{Binding Path=MyItemIsSelected, Mode=TwoWay}"/>
    </Style>
</ListBox.ItemContainerStyle>
从长远来看,这会更好,因为您可以复制
ChildList
对象中的
SelectedItem
行为(添加
myitemsselected
并将其绑定到内部
'ListBoxItem.IsSelected
,如上所述),并将
MySelectedItem
属性添加到
ChildList

ChildItem MySelectedItem
{
   get
   {
      return Items.FirstOrDefault(n=>n.MyItemIsSelected);
   }
}
您的delete命令如下所示:

if (MyItemIsSelected)
{
    ChildItem selItem = ChildItems.MySelectedItem;
    if (selItem != null) ChildItems.Items.Remove(selItem);
}
else
    MyItemIsSelected = true;
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;
   }
}
若所有内容都是数据绑定的,并且列表是
可观察的集合
,那个么您可以在对象中完成所有这些操作,UI也将随之完成。实际上,您只能执行此子选择绑定位,并且仍然可以使用第一种解决方案,在
按钮中单击
如下所示:

if (MyItemIsSelected)
{
    ChildItem selItem = ChildItems.MySelectedItem;
    if (selItem != null) ChildItems.Items.Remove(selItem);
}
else
    MyItemIsSelected = true;
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;
   }
}

下面是一个简单的工作示例,关于

是否必须使用
数据模板
<代码>项目
B项目
可以是
UserControl
。这样,它应该更容易。当点击
按钮
时,您想选择
main项
ListBoxItem
容器,给它焦点还是两者都给它?@NicolasVoron到目前为止,我的整个代码都使用数据模板来绑定不同的ObservableCollection。所以我真的很想坚持这一点。@dkozl当单击这两个按钮中的任何一个时,我想选择包含它们的MainItem ListBoxItem。非常感谢您在回答这个问题时付出的努力。你的解释帮助我从其他方面解决了我的问题。在可观察的集合中,我改变了50%的课程。多亏了你,代码重构比我想象的要容易得多!