WPF - DataTemplateSelector для ListBox не работает
От: senglory  
Дата: 31.08.18 18:20
Оценка:
Вот мой XAML
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:win="clr-namespace:System.Windows;assembly=PresentationCore"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d" 
        >
 
    <Window.Resources>
        <DataTemplate x:Key="DefaultDataTemplate">
        </DataTemplate>
 
        <DataTemplate x:Key="SelectedNoteDataTemplate">
            <StackPanel Background="Orange">
                <TextBlock Text="Name:"  />
                <TextBlock Text="{Binding Name}"   />
            </StackPanel>
        </DataTemplate>
        
        <DataTemplate x:Key="NetworkDataTemplate">
            <StackPanel>
                <TextBlock Text="Name:"  />
                <TextBlock Text="{Binding Name}"   />
            </StackPanel>
        </DataTemplate>
 
        <DataTemplate x:Key="EditNetworkDataTemplate">
            <StackPanel>
                <TextBlock Text="BssID:"  />
                <TextBox Text="{Binding BssID}" />
            </StackPanel>
        </DataTemplate>
 
 
        <local:ListItemTemplateSelector x:Key="viewInListTemplateSelector"
              DefaultnDataTemplate="{StaticResource DefaultDataTemplate}"
              NoteDataTemplate="{StaticResource NetworkDataTemplate}" 
              SelectedNoteDataTemplate="{StaticResource SelectedNoteDataTemplate}" 
                                        />
        <local:ItemTemplateSelector x:Key="editTemplateSelector"
              DefaultnDataTemplate="{StaticResource DefaultDataTemplate}"
              NoteDataTemplate="{StaticResource EditNetworkDataTemplate}" 
                                        />
    </Window.Resources>
 
    
    <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
        <Grid  VerticalAlignment="Stretch" HorizontalAlignment="Stretch" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
 
            <StackPanel Grid.Column="0" Orientation="Vertical">
 
                <ListBox
                    Height="300"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Stretch" 
                    VerticalContentAlignment="Top"
                    x:Name="RecordsList"
                    ItemsSource="{Binding AllRecords}"
                    SelectedItem="{Binding SelectedRec}"
                    ItemTemplateSelector="{StaticResource viewInListTemplateSelector}"
                    />
 
            </StackPanel>
            <StackPanel Grid.Column="1" Orientation="Vertical">
                <ContentControl 
                    VerticalContentAlignment="Stretch" 
                    x:Name="TheRecord"
                    Content="{Binding SelectedRec}"
                    ContentTemplateSelector="{StaticResource ResourceKey=editTemplateSelector}">
                </ContentControl>
            </StackPanel>
        </Grid>
    </StackPanel>
</Window>


Вот код ListItemTemplateSelector

public class ListItemTemplateSelector : DataTemplateSelector
    {
        public DataTemplate DefaultnDataTemplate { get; set; }
        public DataTemplate NoteDataTemplate { get; set; }
        public DataTemplate SelectedNoteDataTemplate { get; set; }
 
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (null == item)
                return DefaultnDataTemplate;
            var lb = container as ListBox;
            if (item == lb.SelectedItem)
                return SelectedNoteDataTemplate;
            else
                return NoteDataTemplate;
        }
    }


Почему при запуске после выполнения lb = container as ListBox lb пусто? В container Listbox не приходит, а приходит ContentPresenter какой-то. Как мне ListItemTemplateSelector выбирать темплейт для Listbox?
Re: WPF - DataTemplateSelector для ListBox не работает
От: takTak  
Дата: 31.08.18 18:29
Оценка:
с binding где-то накосячил, я вообще не понимаю, как можно в 2018 году свои selectors сочинять... опенсорсного добра же дофига...

возьми Snoop да посмотри, на что ты свой лист набайндил
Re[2]: WPF - DataTemplateSelector для ListBox не работает
От: senglory  
Дата: 31.08.18 21:52
Оценка:
Здравствуйте, takTak, Вы писали:

T>с binding где-то накосячил, я вообще не понимаю, как можно в 2018 году свои selectors сочинять... опенсорсного добра же дофига...


T>возьми Snoop да посмотри, на что ты свой лист набайндил


1. Чтобы Snoop взять надо прежде Win 8.1 SDK поставить
2. Если комменчу эту строку, то видно что ListBox привязан правильно, к тому списку, что мне нужен.
Re[3]: WPF - DataTemplateSelector для ListBox не работает
От: takTak  
Дата: 01.09.18 03:47
Оценка:
тогда попробуй пройтись в SelectTemplate по container и найти в нём свой parent или child или чего там

var parent = container;

// Search up the visual tree, stopping at either a ListBox or
// a ListItem (or null). This will determine which template to use
   while(parent != null && !(parent is ListItem) && !(parent is ListBox ))
       parent = VisualTreeHelper.GetParent(parent);

   ...


https://stackoverflow.com/questions/4672867/can-i-use-a-different-template-for-the-selected-item-in-a-wpf-combobox-than-for



то, что ты хочешь, можно сделать и по-другому, с помощью стиля & datatemplate:
https://stackoverflow.com/questions/146269/change-wpf-datatemplate-for-listbox-item-if-selected
Re: WPF - DataTemplateSelector для ListBox не работает
От: ksg71 Германия  
Дата: 02.09.18 06:55
Оценка:
Здравствуйте, senglory, Вы писали:

S>Вот код ListItemTemplateSelector


S>
S>public class ListItemTemplateSelector : DataTemplateSelector
S>    {
S>        public DataTemplate DefaultnDataTemplate { get; set; }
S>        public DataTemplate NoteDataTemplate { get; set; }
S>        public DataTemplate SelectedNoteDataTemplate { get; set; }
 
S>        public override DataTemplate SelectTemplate(object item, DependencyObject container)
S>        {
S>            if (null == item)
S>                return DefaultnDataTemplate;
S>            var lb = container as ListBox;
S>            if (item == lb.SelectedItem)
S>                return SelectedNoteDataTemplate;
S>            else
S>                return NoteDataTemplate;
S>        }
S>    }
S>


S>Почему при запуске после выполнения lb = container as ListBox lb пусто? В container Listbox не приходит, а приходит ContentPresenter какой-то. Как мне ListItemTemplateSelector выбирать темплейт для Listbox?


SelectTemplate вызывается до приcвоения нового значение свойства SelectedItem
нужно в item соотв. свойство завести — выбран он или нет, выглядит может и избыточно но работать должно
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Re[4]: WPF - DataTemplateSelector для ListBox не работает
От: senglory  
Дата: 02.09.18 20:41
Оценка:
Попытался перенести стиль в темплейт:

        <DataTemplate x:Key="NetworkDataTemplate">
            <ListBoxItem>
                <ListBoxItem.Style>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Style.Triggers>
                            <Trigger Property="IsSelected" Value="True" >
                                <Setter Property="Background" Value="Orange" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </ListBoxItem.Style>
                <StackPanel>
                    <TextBlock Text="Name:"  />
                    <TextBlock Text="{Binding Name}"   />
                </StackPanel>
            </ListBoxItem>
        </DataTemplate>


И никакого эффекта. Т.е. не то что оранжевым выбранный не окрашивается, а вообще он не меняется. ЧЯДНТ?
Re[2]: WPF - DataTemplateSelector для ListBox не работает
От: senglory  
Дата: 02.09.18 20:46
Оценка:
K>SelectTemplate вызывается до приcвоения нового значение свойства SelectedItem
K>нужно в item соотв. свойство завести — выбран он или нет, выглядит может и избыточно но работать должно

Так в ListBoxItem и так есть свойство IsSelected, зачем еще и в данных его заводить?
Re[5]: WPF - DataTemplateSelector для ListBox не работает
От: takTak  
Дата: 02.09.18 21:02
Оценка:
S>И никакого эффекта. Т.е. не то что оранжевым выбранный не окрашивается, а вообще он не меняется. ЧЯДНТ?

опять изобретаешь свой велосипед, не понимая, что именно ты делaешь, возьми один-в-один пример, на котором на stackoverflow 170 подтверждений, обрати внимание, что у тебя в проекте нет переопределённых стилей где-то ещё, тогда всё должно работать, после этого пробуешь изменять какие-то другие, нежели указанные свойства

посмотрел в тот пример, на который я ссылался, там меняется Foreground, вот начни с него и один-в-один с приведённого примера,

snoop тебе тоже поможет, там ошибки в привязке тоже видны, как видны они и в debug-окошке visual studio, если ты изменишь свойства , просто погугли как эти настройки изменить
Re[3]: WPF - DataTemplateSelector для ListBox не работает
От: ksg71 Германия  
Дата: 03.09.18 10:37
Оценка: 6 (1)
Здравствуйте, senglory, Вы писали:

K>>SelectTemplate вызывается до приcвоения нового значение свойства SelectedItem

K>>нужно в item соотв. свойство завести — выбран он или нет, выглядит может и избыточно но работать должно

S>Так в ListBoxItem и так есть свойство IsSelected, зачем еще и в данных его заводить?


да, в WPF и это не работает, DataTemplate выбирается только при добавлении элемента(биндинге) коллекции и потом уже на изменение его свойств не реагирует.
тогда в твоем случае надо выбирать темплейт для разных типов в селекторе, а выбранность обрабатывать в каждом из них через стиль например

<ListBox x:Name="listBox" VerticalAlignment="Top" 
                 ItemsSource="{Binding Items}"
                 SelectedItem="{Binding SelectedItem}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel.Style>
                            <Style TargetType="StackPanel">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsSelected}" 
                                                 Value="True">
                                        <Setter Property="Background" Value="Orange" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </StackPanel.Style>
                        <TextBlock Text="Name:"  />
                        <TextBlock Text="{Binding Name}"   />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
Das Reich der Freiheit beginnt da, wo die Arbeit aufhört. (c) Karl Marx
Отредактировано 03.09.2018 10:38 ksg71 . Предыдущая версия .
Re: конфликт сборок
От: Codechanger Россия  
Дата: 04.09.18 15:05
Оценка:
Здравствуйте, senglory, Вы писали:



S>Почему при запуске после выполнения lb = container as ListBox lb пусто? В container Listbox не приходит, а приходит ContentPresenter какой-то. Как мне ListItemTemplateSelector выбирать темплейт для Listbox?

Переопредели ItemContainerStyle, сделай у объекта свойство IsSelected и забинди его в стиле на LIstBoxItem.IsSelected
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.