1

Я новичок в создании пользовательского контроля. Я заложил основу для нового пользовательского элемента управления, основанного на классе Selector. Мое понимание заключалось в том, что я должен использовать этот класс, поскольку мне нужен элемент управления, чтобы иметь коллекцию Items и способность обрабатывать выбранные элементы. Я считаю, что изменение ItemTemplate, возможно, превзошло некоторые из этих возможностей, потому что я не получаю событие SelectionChanged на уровне управления или уровне приложения. Я бы подумал, если я прав, что есть какой-то тег SelectionRegion XAML, в который я могу вставить встроенные DataTemplate. Мне не повезло найти что-нибудь подобное. Посмотрев через Google некоторое время, я готов только спросить. Что мне не хватает? Ниже приведена разметка ItemTemplate. Спасибо за любую помощь. Спасибо еще больше, если вы можете сказать мне, почему текст в TextBlock заключен в круглые скобки, даже если данные отсутствуют.WPF - Селектор - Пользовательский контроль - SelectionChanged Event Not Firing

<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? –

+0

из моего понимания селекторного класса, если вы проистекаете из него, то событие выбора нужно обрабатывать самостоятельно, будь то нажатие мыши, касание или клавиатура. если вы хотите иметь уже реализованное событие выбора, используйте listview или listbox. CMIIW. – dnr3

+0

@ dnr3 Итак, точка использования класса Selector заключается только в том, что у него есть все переменные-члены для поддержки выбора? Это кажется немного бесполезным. – BillyD

ответ

0

Из нескольких примеров кода с различными элементами управления, я считаю, что мой ответ заключается в том, что я делаю все это неправильно. Вместо этого мне нужно иметь элемент управления, который имеет Selector, как ListBox в ControlTemplate. Тогда, совет @JKing поможет мне добраться туда, где я должен быть. Ответ на фактический вопрос, который задан, но является вышеупомянутым изменением от использования Selector в качестве базового класса, чтобы иметь селектор в шаблоне для элемента управления. Спасибо за помощь.

+0

Имеет смысл, у меня возникли проблемы с попыткой выяснить, что вы пытаетесь выполнить, удачи. Я рекомендую смотреть с визуальным шаблоном студии для пользовательских элементов управления, а затем изучать некоторые примеры текстовых полей автозаполнения в google, у них есть примеры в текстовом поле, которое фильтрует результаты списка. –

0

здесь что я делаю. Я использую функцию шаблона apply для настраиваемого элемента управления и добавляю handlerto к выбранному 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; 
} 

вы можете связать с именем публичного мероприятия (YourControlSelectionChanged) вы объявлены в пользовательском классе управления в XAML.

надеюсь, что это поможет.

+0

Похоже, вы думаете об этом как о пользователе. Возможно, я ошибаюсь. В вашем примере класс, в котором находится OnApplyTemplate, является селектором. То, что я ищу, - это способ поймать RoutedEvent из TextBlock или Border в ItemTemplate и передать его в базовый класс Selector, чтобы он работал со своей магией, рассказывая мне, какой элемент был выбран на новом уровне настраиваемого уровня управления. Затем я могу выполнить всю необходимую обработку перед отправкой события на уровень окна, который изменил выбор. – BillyD

+0

Кстати, я попытался использовать вариацию вашей логики, чтобы назвать границу в ItemTemplate и добавить туда делегата. Однако он не может найти имя. Я полагаю, что это потому, что this.Template может не включать Ресурсы или может отсутствовать из-за того, что нет данных (никаких элементов для рендеринга еще не было). – BillyD

+0

Это defninitly из пользовательского элемента управления. Ваш пользовательский контроль происходит от базового Селектора, у которого есть выделенное событие. Я не понимаю, почему это событие не даст вам желать лучшего. Как я вижу, вы просто хотите получить уведомление об изменении выбора/объекта в вашем коде. Если вы не хотите раскрывать это событие своего пользовательского элемента управления, вы все равно можете использовать его в своем специальном элементе управления «code behind» для обработки вашей логики управления. Зачем вам нужен текстовый блок или рамка для создания этого события? –