2013-04-24 169 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

相关问题