Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
1245 / 1055 / 293
Регистрация: 07.03.2012
Сообщений: 3,245
1

Получить ListBoxItem из DataTemplate

30.08.2014, 18:57. Показов 1664. Ответов 6
Метки wpf (Все метки)

Author24 — интернет-сервис помощи студентам
Имеется ListBox, использующий DataTemplate:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
 <DataTemplate x:Key="ProductSearchTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Converter={StaticResource ItemToNumberConverter}, RelativeSource={RelativeSource Self}}"/>
                <TextBlock Text="{Binding ProductName}" Grid.Column="1" TextTrimming="WordEllipsis"/>
                <Image Grid.Column="2" Width="45" Source="Resources/arrowForward.png"/>
                
            </Grid>
        </DataTemplate>
Вот мне нужно в Text первого TextBlock вписать номер ListBoxItem в ListBox. Это winPhone, AncestorType здесь нет. В конвертер таким образом я передаю сам TextBlock. Как бы мне получить ListBoxItem в котором находится этот TextBlock?

Надеюсь на вашу помощь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.08.2014, 18:57
Ответы с готовыми решениями:

Добавление listBoxItem кодом, с немного изменённым dataTemplate
Есть вот такой treewiew (написал listbox, т.к. это понятней и различий в добавлении item'ов нет)...

Получить текст выделенного ListBoxItem
не могу получить текст выделенного ListBoxItem ошибка &quot;Ссылка на объект не указывает на экземпляр...

Как получить доступ к Button в DataTemplate?
Здравствуйте! Нужна ваша помощь. Есть код: &lt;DataGrid Name=&quot;dataGrid&quot; Margin=&quot;7,7,7,0&quot;...

Не получается получить доступ к элементу внутри DataTemplate
В чем моя ошибка, подскажите пожалуйста. VisualTreeHelper.GetChildrenCount(parent) - данный метод...

6
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
30.08.2014, 20:41 2
А почему нужно получать номер именно из ListBoxItem? Нужен порядковый номер ListBoxItem из ListBox(а)?
0
1245 / 1055 / 293
Регистрация: 07.03.2012
Сообщений: 3,245
30.08.2014, 21:58  [ТС] 3
Цитата Сообщение от Casper-SC Посмотреть сообщение
Нужен порядковый номер ListBoxItem из ListBox(а)?
да, индекс его.
не на винфоне (и для listView) я писал так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public class IndexConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ListViewItem item = (ListViewItem)value;
            ListView lv = (ListView) ItemsControl.ItemsControlFromItemContainer(item);
            return (lv.ItemContainerGenerator.IndexFromContainer(item)+1).ToString();
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }
но сейчас у меня у value тип TextBlock. Там ещё св-во Parent есть у него, думал, через него смогу достать ListBoxItem, но оно null всегда
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
30.08.2014, 22:17 4
А почему не сделать так?

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<Window x:Class="Wpf_LbItemNumber.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfLbItemNumber="clr-namespace:Wpf_LbItemNumber"
        Title="MainWindow"
        Width="525"
        Height="350"
        Loaded="Window_Loaded">
 
    <Window.Resources>
 
        <wpfLbItemNumber:ItemToNumberConverter x:Key="ItemToNumberConverter" />
 
        <DataTemplate x:Key="ProductSearchTemplate"
                      DataType="wpfLbItemNumber:SomethingViewModel">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Number}" />
                <TextBlock Grid.Column="1"
                           Text="{Binding ProductName}"
                           TextTrimming="WordEllipsis" />
                <!--
                    <Image Grid.Column="2"
                    Width="45"
                    Source="Resources/arrowForward.png" />
                -->
 
            </Grid>
        </DataTemplate>
    </Window.Resources>
 
    <Window.DataContext>
        <wpfLbItemNumber:MainViewModel />
    </Window.DataContext>
 
    <Grid>
        <ListBox x:Name="listBox"
                 Margin="10"
                 ItemTemplate="{StaticResource ProductSearchTemplate}"
                 ItemsSource="{Binding Collection}" />
    </Grid>
</Window>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Windows;
 
namespace Wpf_LbItemNumber
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var main = (MainViewModel) DataContext;
            main.Generate();
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Collections.ObjectModel;
 
namespace Wpf_LbItemNumber
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            Collection = new ObservableCollection<SomethingViewModel>();
        }
 
        public ObservableCollection<SomethingViewModel> Collection { get; set; }
 
        public void Generate()
        {
            for (int i = 0; i < 10; i++)
            {
                var something = new SomethingViewModel(new Something("Товар"));
                Collection.Add(something);
                something.Number = i + 1; //Collection.IndexOf(something); 
            }
        }
    }
}
Добавлено через 1 минуту
Если важно, чтобы именно номер ячейки всегда был слева, то можно так же просто обновлять Number при перемещении, удалении данных из коллекции.

Добавлено через 1 минуту
Цитата Сообщение от Монфрид Посмотреть сообщение
но сейчас у меня у value тип TextBlock. Там ещё св-во Parent есть у него, думал, через него смогу достать ListBoxItem, но оно null всегда
Была бы у меня возможность поработать с WinPhone проектом, то может бы что-то и придумал.
1
1245 / 1055 / 293
Регистрация: 07.03.2012
Сообщений: 3,245
30.08.2014, 22:31  [ТС] 5
Цитата Сообщение от Casper-SC Посмотреть сообщение
А почему не сделать так?
этот вариант я конечно же рассматривал, но класс модели - это структура таблицы бд. Да и заполнять св-во Number при каждом получении данных как то не очень здорово
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
30.08.2014, 22:42 6
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<Window x:Class="Wpf_LbItemNumber.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfLbItemNumber="clr-namespace:Wpf_LbItemNumber"
        Title="MainWindow"
        Width="525"
        Height="350"
        Loaded="Window_Loaded">
 
    <Window.Resources>
 
        <wpfLbItemNumber:NumberPlusNumberConverter x:Key="NumberPlusNumberConverter" />
 
        <DataTemplate x:Key="ProductSearchTemplate"
                      DataType="wpfLbItemNumber:SomethingViewModel">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent},
                    Path=TemplatedParent.(ItemsControl.AlternationIndex), 
                    Converter={StaticResource NumberPlusNumberConverter}, 
                    ConverterParameter=1}" />
                <TextBlock Grid.Column="1"
                           Text="{Binding ProductName}"
                           TextTrimming="WordEllipsis" />
                <!--
                    <Image Grid.Column="2"
                    Width="45"
                    Source="Resources/arrowForward.png" />
                -->
 
            </Grid>
        </DataTemplate>
    </Window.Resources>
 
    <Window.DataContext>
        <wpfLbItemNumber:MainViewModel />
    </Window.DataContext>
 
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="281*" />
            <RowDefinition Height="39*" />
        </Grid.RowDefinitions>
 
        <ListBox x:Name="listBox"
                 Margin="10,10,10,0"
                 AlternationCount="{Binding Path=Collection.Count}"
                 ItemTemplate="{StaticResource ProductSearchTemplate}"
                 ItemsSource="{Binding Collection}" />
    </Grid>
</Window>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
using System;
using System.Globalization;
using System.Windows.Data;
 
namespace Wpf_LbItemNumber
{
    [ValueConversion(typeof(int), typeof(int))]
    public class NumberPlusNumberConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int plusNumber = 0;
            if (parameter != null)
            {
                int.TryParse((string) parameter, out plusNumber);
            }
            return (int)value + plusNumber;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Binding.DoNothing;
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Windows;
 
namespace Wpf_LbItemNumber
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var main = (MainViewModel) DataContext;
            main.Generate();
        }
    }
}
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
 
namespace Wpf_LbItemNumber
{
    public class Something
    {
        public Something()
            : this(string.Empty)
        {
        }
 
        public Something(string productName)
        {
            ProductName = productName;
        }
 
        public string ProductName { get; set; }
    }
 
    public class SomethingViewModel : ViewModelBase
    {
        private readonly Something _something;
 
        public SomethingViewModel(Something something)
        {
            _something = something;
        }
 
        public string ProductName
        {
            get { return _something.ProductName; }
            set
            {
                _something.ProductName = value;
                RaisePropertyChanged("ProductName");
            }
        }
 
        public Something Something
        {
            get { return _something; }
        }
    }
 
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
1
1245 / 1055 / 293
Регистрация: 07.03.2012
Сообщений: 3,245
30.08.2014, 23:21  [ТС] 7
Цитата Сообщение от Casper-SC Посмотреть сообщение
XML
1
2
3
4
5
<ListBox x:Name="listBox"
Margin="10,10,10,0"
AlternationCount="{Binding Path=Collection.Count}"
ItemTemplate="{StaticResource ProductSearchTemplate}"
 ItemsSource="{Binding Collection}" />
не, AlternationCount нет в винфоне)
0
30.08.2014, 23:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.08.2014, 23:21
Помогаю со студенческими работами здесь

Как получить доступ к контролу в DataTemplate из code behind
var s = (Button)FindName(&quot;Button_Done&quot;); эта строка возвращает Null, как получить реальный объект?...

TextWrapping для ListBoxItem
Требуется, чтобы текст внутри ListBoxItem переносился если не вмешается в габариты ListBox. Юзаю...

Grid внутри ListBoxItem
Всем привет. Мне необходимо чтобы внутри ListBoxItem располагался Grid, который занимает всю...

Добавление кнопки в ListBoxItem
Здравсвуйте, столкнулся с такой проблемой. Необходимо добавить кнопку в listboxitem.В listboxitem'е...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru