2010-01-26 73 views
2

我創建了一個自定義的ComboBox如下:(注意,代碼是不正確的,但你應該得到的總體思路。)的ComboBox包含關係2個依賴屬性:TitleTextDescriptionText綁定到所選擇的項目在一個ItemsControl

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

我想用這個ComboBox顯示廣泛的選擇。我創建了一個類中調用設置從DependencyObject繼承來創建可用的項目,我創建了一個DataTemplate這個Settings對象的內容綁定到我的ComboBox並創建了一個UserControl其中包含ItemsControl具有作爲我前面提到的DataTemplate的模板。我可以用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> 

我想有所選ComboBox被放置在DescriptionTextBlock在我UserControl(由任一ComboBox控制或彈出窗口的IsOpen屬性的IsFocus選擇的)的DescriptionText

的一種方式,我設法實現這一目標是取代我ItemsControlListBox但這引起幾個問題:它總是顯示滾動條,即使我禁用它,它也不會趕上焦點時,我的彈出是開放的,但只有當我明確選定的項目在我ListBox,當我啓用了OverridesDefaultStyle財產ListBox的內容不會顯示在所有,我不得不重新主題ListBox控制,以配合我UserControl佈局...

有什麼最好和最簡單的方式讓我的DescriptionText不使用ListBox或創建自定義Selector控制(因爲它具有與ListBox相同的效果)?

末的目標是要遍歷所有的項目(也許讓他們進入一個ObservableCollection或某種並將其保存到我的設置文件。

+0

這還不完全清楚對我來說,你在這裏嘗試。你有一個代碼隱藏,或者你只是使用綁定? – codekaizen 2010-01-26 19:58:42

+0

我有一個代碼背後的代碼,但目前它沒有真正使用。 當您選擇ComboBox項目(獲得焦點或彈出窗口打開)時,每個組合框都包含有關其所更改選項的小說明,該想法是使用正確的描述更新右側的描述文本塊。 – Jensen 2010-01-26 20:08:14

回答

1

我想我知道你這是一個可能的解決方案

您應該使用ListBox(或從Selector控件派生的任何東西)以使用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; 
    } 
} 

什麼這個小類的作用是幫助你控制把重點放在列表框選擇項目時您激活其內部控制(即你的組合框)。它在ListBox項目內單擊鼠標時起作用。

現在,所有你需要做的是將其連接到您的組合框,如下所示:

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

其中ControlHelper是:

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

最後,禁用(但我建議設置爲Auto)滾動條,你可以在你的列表框中使用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 > 
0

您可以使用一個列表框,只需更改數據如何呈現。例如,下面的代碼將默認爲不具有滾動條。(我想滾動條,所以我必須明確地包裹在ScrollViewer中整個事情。)

   <ListBox.Template> 
        <ControlTemplate> 
         <StackPanel IsItemsHost="True" > 
         </StackPanel> 
        </ControlTemplate> 
       </ListBox.Template>