2013-04-24 266 views
1

我是新來的自定義控件創建。我已經爲基於Selector類的新自定義控件奠定了一些基礎。我的理解是我應該使用這個類,因爲我需要控件擁有一個Items集合和處理選擇的能力。我相信更改ItemTemplate可能會覆蓋一些此功能,因爲我沒有在控制級別或應用程序級別收到SelectionChanged事件。我想如果我是對的,有某種SelectionRegion XAML標籤可以放入DataTemplate內部。我找不到這樣的運氣。在瀏覽谷歌一段時間之後,我已經準備好提問了。我錯過了什麼?以下是ItemTemplate標記。謝謝你的幫助。如果您能告訴我爲什麼TextBlock中的文本被括在圓括號中,即使數據不是,也要多謝。WPF - 選擇器 - 自定義控件 - SelectionChanged事件不會觸發

<Setter Property="ItemTemplate"> 
    <Setter.Value> 
     <DataTemplate> 
      <Border BorderBrush="Black" BorderThickness="1"> 
       <TextBlock Text="{Binding}" Foreground="Black" Background="White" MinHeight="12" MinWidth="50"/> 
      </Border> 
     </DataTemplate> 
    </Setter.Value> 
</Setter> 

在一個評論者的要求,這裏是控制整個XAML至今:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SourceMedicalWPFCustomControlLibrary"> 
    <Style TargetType="{x:Type local:MultiStateSelectionGrid}"> 
     <Setter Property="ItemsPanel"> 
      <Setter.Value> 
       <ItemsPanelTemplate> 
        <WrapPanel/> 
       </ItemsPanelTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="ItemTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
        <Border BorderBrush="Black" BorderThickness="1"> 
         <TextBlock Text="{Binding Code}" Foreground="Black" Background="White" MinHeight="12" MinWidth="50" Padding="2" ToolTip="{Binding Description}"/> 
        </Border> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:MultiStateSelectionGrid}"> 
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,0" Background="{TemplateBinding Background}"> 
         <ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,0" Content="{TemplateBinding Content}"/> 
         <ItemsPresenter/> 
        </StackPanel> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

而且貧血代碼隱藏,以及:

namespace SourceMedicalWPFCustomControlLibrary 
{ 
    public class MultiStateSelectionGridState 
    { 
     public Brush Background { get; set; } 
     public Brush Foreground { get; set; } 
     public Brush Border { get; set; } 
     public string Text { get; set; } 

     public MultiStateSelectionGridState() 
     { 
      Background = Brushes.White; 
      Foreground = Brushes.Black; 
      Border = Brushes.Black; 
      Text = String.Empty; 
     } 
    }; 

    public class MultiStateSelectionGrid : Selector 
    { 
     public static readonly DependencyProperty ContentProperty = 
      DependencyProperty.Register("Content", typeof(object), typeof(MultiStateSelectionGrid), 
      new FrameworkPropertyMetadata(null, 
        FrameworkPropertyMetadataOptions.AffectsRender | 
        FrameworkPropertyMetadataOptions.AffectsParentMeasure)); 

     public object Content 
     { 
      get { return (object)GetValue(ContentProperty); } 
      set { SetValue(ContentProperty, value); } 
     } 

     public static readonly DependencyProperty StatesProperty = 
      DependencyProperty.Register("States", typeof(List<MultiStateSelectionGridState>), typeof(MultiStateSelectionGrid), 
      new FrameworkPropertyMetadata(new List<MultiStateSelectionGridState>(), 
       FrameworkPropertyMetadataOptions.AffectsRender)); 

     public List<MultiStateSelectionGridState> States 
     { 
      get { return (List<MultiStateSelectionGridState>)GetValue(StatesProperty); } 
      set { SetValue(StatesProperty, value); } 
     } 

     static MultiStateSelectionGrid() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiStateSelectionGrid), new FrameworkPropertyMetadata(typeof(MultiStateSelectionGrid))); 
     } 

     public override void OnApplyTemplate() 
     { 
      base.OnApplyTemplate(); 
      this.SelectionChanged += new SelectionChangedEventHandler(MultiStateSelectionGrid_SelectionChanged); 
     } 

     void MultiStateSelectionGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) 
     { 
      MessageBox.Show("Hi"); 
     } 
    } 
} 
+0

歡迎來到堆棧溢出。我們需要更多的細節,什麼是你的控制的完整xaml和背後的代碼,或者如果使用mvvm查看模型? – 2013-04-25 04:47:38

+0

根據我對選擇器類的理解,如果你從它中派生出來,那麼選擇事件需要由你自己來處理,無論是通過鼠標點擊,觸摸還是鍵盤。如果你想有一個已經實現的選擇事件,可以使用listview或者listbox。 CMIIW。 – dnr3 2013-04-25 06:51:51

+0

@ dnr3那麼,使用Selector類的關鍵就在於它具有所有成員變量來支持選擇?這似乎有點無用。 – BillyD 2013-04-25 13:10:51

回答

0

從閱讀一些完整的不同控件的完整代碼示例,我相信我的答案是我這樣做都是錯誤的。相反,我需要在ControlTemplate中擁有像ListBox那樣的Selector控件。那麼,@JKing的建議會幫助我達到我需要的地方。實際問題的答案雖然是從使用Selector作爲基類到在控件的模板中具有選擇器的前述變化。謝謝您的幫助。

+0

有道理,我試圖弄清楚你正在努力完成什麼,我很困難,祝你好運。我建議用自定義控件的視覺工作室模板,然後研究谷歌中的一些自動填充文本框示例,他們在文本框中列出了篩選列表框結果的示例。 – 2013-04-25 17:21:31

0

這裏我做的事。我使用自定義控件的應用模板函數,並添加一個句柄來選擇我想要的控件的chnaged事件。

簡單的樣品在這裏:

public event EventHandler<SelectionChangedEventArgs> YourControlSelectionChanged; 

private void Selector_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (ListSelectionChanged != null) { 
     ListSelectionChanged(sender, e); 
    } 
} 

public override void OnApplyTemplate() 
{ 
    base.OnApplyTemplate(); 
    //find or declare your control here, the x:name in xaml should be YourControl 
    YourControl== this.Template.FindName("YourControl", this) as YourControlType 
    YourControl.SelectionChanged += ResultListBox_SelectionChanged; 
} 

然後你可以綁定到你在XAML自定義控件類中聲明的公共事件(YourControlSelectionChanged)的名稱。

希望這有助於。

+0

它看起來像你正在考慮這是一個用戶控件。我可能是錯的。在你的例子中,OnApplyTemplate所在的類是一個Selector。我正在尋找的是從ItemTemplate中的TextBlock或Border中捕獲RoutedEvent並將其饋送到Selector基類的方法,以便它能夠在告訴我在新的自定義控件類級別選擇哪個Item時發揮它的魔力。然後,我可以在將事件發送到窗口級別之前進行所需的任何處理,以便發生選擇更改。 – BillyD 2013-04-25 15:30:00

+0

順便說一句,我嘗試使用你的邏輯變體來命名ItemTemplate中的邊框並在那裏添加一個委託。它雖然找不到名字。我認爲這是因爲這個.Template可能不包含資源,或者由於沒有數據存在(沒有必要渲染的項目),它可能會丟失。 – BillyD 2013-04-25 15:33:20

+0

這是自定義控件的定義。您的自定義控件來自具有selectionchnaged事件的基本選擇器。我不明白爲什麼這個事件不會讓你想要你想要的。正如我所看到的那樣,您只是希望得到關於您的代碼背後的選擇/對象更改的通知。如果你不想公開你的自定義控件的這個事件,你仍然可以在你的自定義控件「後面的代碼」中使用它來處理你的控制邏輯。爲什麼你需要文本塊或邊框來生成此事件? – 2013-04-25 15:38:02

相關問題