代码之家  ›  专栏  ›  技术社区  ›  Jensen

绑定到itemscontrol中的选定项

  •  2
  • Jensen  · 技术社区  · 15 年前

    我创建了一个自定义 ComboBox 如下:(注意,代码是不正确的,但您应该得到一般的想法。)的 组合框 包含两个重要的依赖属性: TitleText DescriptionText .

    <Grid>
      <TextBlock x:Name="Title"/>
      <Grid x:Name="CBG">
        <ToggleButton/>
        <ContentPresenter/>
        <Popup/>
      </Grid>
    </Grid>
    

    我想用这个 组合框 显示各种选项。我创建了一个名为setting的类,它继承自 DependencyObject 为了创建可用的项目,我创建了一个 DataTemplate 绑定此内容 Settings 反对我的 组合框 创造了一个 UserControl 其中包含 ItemsControl 作为我之前提到的模板 数据板 .我可以把它装满 Setting 物体。

    <DataTemplate x:Key="myDataTemplate">
      <ComboBox TitleText="{Binding Title}" DescriptionText="{Binding DescriptionText}"/>
    </DataTemplate>
    
    <UserControl>
      <Grid>
        <StackPanel Grid.Column="0">
          <ItemsControl Template="{StaticResource myDataTemplate}">
            <Item>
              <Setting Title="Foo" Description="Bar">
                <Option>Yes</Option><Option>No</Option>
              </Setting>
            </Item>
          </ItemsControl>
        </StackPanel>
        <StackPanel Grid.Column="1">
          <TextBlock x:Name="Description"/>
        </StackPanel>
      </Grid>
    </UserControl>
    

    我想要 描述文本 选定的 组合框 (由 IsFocus 组合框 控制或 IsOpen 弹出窗口的属性)。 Description TextBlock 在我的 用户控制 .

    我成功做到这一点的一个方法是取代我的 项目控制 由A ListBox 但这导致了几个问题:它总是显示滚动条,即使我禁用了它,它也不会在弹出窗口打开时捕获焦点,但只有当我在 列表框 ,当我启用 OverridesDefaultStyle 属性的内容 列表框 根本不会出现,我必须重新设计主题 列表框 控件以匹配我的 用户控制 布局…

    什么是最好和最简单的方法来获得我的 描述文本 不使用 列表框 或创建自定义 Selector 控制(与 列表框 )是吗?

    最后的目标是循环遍历所有项(可能将它们放入 ObservableCollection 或者某种排序,并将它们保存到我的设置文件中。

    2 回复  |  直到 12 年前
        1
  •  1
  •   Tri Q Tran    15 年前

    我想我知道你想做什么。这里有一个可能的解决方案。

    为了使用SelectedItem属性,应该使用列表框(或从选择器控件派生的任何内容)。

    <UserControl>
      <Grid>
        <StackPanel Grid.Column="0">
          <ListBox x:Name="SettingListBox" Template="{StaticResource myDataTemplate}">
            <Item>
              <Setting Title="Foo" Description="Bar">
                <Option>Yes</Option><Option>No</Option>
              </Setting>
            </Item>
          </ListBox >
        </StackPanel>
        <StackPanel Grid.Column="1">
          <TextBlock x:Name="Description"
              Text="{Binding SelectedItem.Description, ElementName=SettingListBox}"/>
        </StackPanel>
      </Grid>
    </UserControl>
    

    为了解决当您打开组合框下拉菜单时,列表框不关注项目的问题,我有一个附加属性可以为您解决这个问题。

    public class ListBoxHelper
    {
        #region Dependency Property
    
        public static bool GetCanFocusParent(DependencyObject obj)
        {
            return (bool)obj.GetValue(CanFocusParentProperty);
        }
    
        public static void SetCanFocusParent(DependencyObject obj, bool value)
        {
            obj.SetValue(CanFocusParentProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for CanFocusParent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CanFocusParentProperty =
            DependencyProperty.RegisterAttached("CanFocusParent", typeof(bool), typeof(ListBoxHelper), new UIPropertyMetadata(false, OnCanFocusParentChanged));
    
    
    
        #endregion
    
        private static void OnCanFocusParentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            var element = obj as UIElement;
            if(element == null) return;
    
            if((bool)args.NewValue)
                element.PreviewMouseDown += FocusOnParent;
            else
                element.PreviewMouseDown -= FocusOnParent;
        }
    
        private static void FocusOnParent(object sender, RoutedEventArgs e)
        {
            var listBoxItem = VisualUpwardSearch<ListBoxItem>(sender as DependencyObject) as ListBoxItem;
            if (listBoxItem != null) listBoxItem.IsSelected = true;
        }
    
        public static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
        {
            while (source != null && source.GetType() != typeof(T))
                source = VisualTreeHelper.GetParent(source);
    
            return source;
        }
    }
    

    这个小类所做的是帮助控件在激活列表框中的控件(即组合框)时聚焦于所选的列表框项。当在列表框项中单击鼠标时,它会工作。

    现在你要做的就是像这样把它连接到你的组合框上:

    <DataTemplate x:Key="myDataTemplate">
      <ComboBox
          TitleText="{Binding Title}"
          DescriptionText="{Binding DescriptionText}"
          CotrolHelper:ListBoxHelper.CanFocusParent="true"/>
    </DataTemplate>
    

    其中controlHelper是:

    xmlns:ControlHelper="clr-namespace:WhereYouPutYour.ListBoxHelperClass"
    

    最后,要禁用滚动条(但我建议将其设置为自动),可以使用列表框中的ScrollViewer附加属性,如下所示:

    <ListBox
        x:Name="SettingListBox"
        Template="{StaticResource myDataTemplate}"
        ScrollViewer.VerticalScrollBarVisibility="Disabled" >
        <Item>
            <Setting Title="Foo" Description="Bar">
                <Option>Yes</Option><Option>No</Option>
            </Setting>
        </Item>
    </ListBox >
    
        2
  •  0
  •   Jonathan Allen    15 年前

    您可以使用列表框,只需更改数据的显示方式。例如,此代码将默认为没有滚动条。(我需要滚动条,所以我必须在滚动查看器中显式包装整个内容。)

                    <ListBox.Template>
                        <ControlTemplate>
                            <StackPanel IsItemsHost="True" >
                            </StackPanel>
                        </ControlTemplate>
                    </ListBox.Template>
    
    推荐文章