powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / DataGrid с кнопкой в строке
9 сообщений из 9, страница 1 из 1
DataGrid с кнопкой в строке
    #39353065
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет всем, нашел интересный пример Datagrid c кнопками в строках( http://losev-al.blogspot.ru/2012/09/blog-post_26.html ) и хотел реализовать такой же, только с использованием MVVM паттерна.
Создал ViewModel
Код: vbnet
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.
Public Class ViewModel
    Inherits DependencyObject
    Private m_Collection As ObservableCollection(Of Item)
    Public Shared ReadOnly ItemsProperty As DependencyProperty = DependencyProperty.Register("Items", GetType(ObservableCollection(Of Item)), GetType(MainWindow), New PropertyMetadata(Nothing))
    Public Shared ReadOnly DeleteCommandProperty As DependencyProperty = DependencyProperty.Register("DeleteCommand", GetType(ICommand), GetType(MainWindow), New PropertyMetadata(Nothing))

    Public Property Items() As ObservableCollection(Of Item)
        Get
            Return DirectCast(GetValue(ItemsProperty), ObservableCollection(Of Item))
        End Get
        Set
            SetValue(ItemsProperty, Value)
        End Set
    End Property


    Public Property DeleteCommand() As ICommand
        Get
            Return DirectCast(GetValue(DeleteCommandProperty), ICommand)
        End Get
        Set
            SetValue(DeleteCommandProperty, Value)
        End Set
    End Property

    Sub New()
        Items = Item.GetItems()
        DeleteCommand = New MyCommand() With {.Collection = Items}
    End Sub

    Private Class MyCommand
        Implements ICommand
        Public Property Collection() As ObservableCollection(Of Item)
            Get
                Return m_Collection
            End Get
            Set
                m_Collection = Value
            End Set
        End Property
        Private m_Collection As ObservableCollection(Of Item)
        Public Event CanExecuteChanged As EventHandler
        Private Event ICommand_CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged

        Private Function ICommand_CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
            Return True
        End Function

        Private Sub ICommand_Execute(parameter As Object) Implements ICommand.Execute
            Collection.Remove(TryCast(parameter, Item))
        End Sub
    End Class
End Class


и переписал xaml- разметку

Код: 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.
56.
57.
58.
59.
<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_test"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources >
        <local:ViewModel x:Key="VM"/>
    </Window.Resources>

    <Grid>
        <DataGrid  DataContext="{Binding Source={StaticResource VM}}" x:Name="dgMain" AutoGenerateColumns="False" CanUserAddRows="False" Margin="5"
            SelectionMode="Extended" SelectionUnit="Cell"
            ItemsSource="{Binding Path=Items}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Имя" Binding="{Binding Name}" Width="1*" />
                <DataGridTemplateColumn Header="Процент" Width="100">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Percent,StringFormat={}{0}%}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="1*" />
                                    <ColumnDefinition Width="auto" />
                                </Grid.ColumnDefinitions>
                                <TextBox Text="{Binding Percent,Mode=TwoWay}" />
                                <TextBlock Grid.Column="1" Text="%" />
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Width="30">
                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}" >
                            <Setter Property="Background" Value="White"></Setter>
                            <Setter Property="Foreground" Value="White"></Setter>
                            <Setter Property="BorderBrush" Value="White"></Setter>
                            <Setter Property="BorderThickness" Value="1"></Setter>
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="Х" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding}" />


                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        
    </Grid>
</Window>



Данные отображаются, но событие нажатия кнопки не срабатывает. Ставил точку останова на
Код: vbnet
1.
 Private Function ICommand_CanExecute

- до нее не доходит. Пробовал менять в DependencyProperty.Register "MainWindow" на "ViewModel" - не помогло плюс стало писать ошибку о ненахождении свойства "DeletedCommand". Гуглом гуглил- не помогло. Подскажите кто в курсе.
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39353140
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DataContext объявлен на уровне грида, то есть там ваша вьюмодель, не выше.

А привязку команды вы пытаетесь выполнить на уровень Window - там нет никакой вьюмодели.
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39353536
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
пробовал следующие варианты:
DataContext на уровне Datagrid
1)
Код: xml
1.
 <Button Content="Х" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type  DataGrid }}}" CommandParameter="{Binding}" />


кнопки стали неактивны
2)
Код: xml
1.
  <Button Content="Х" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type  DataGridTemplateColumn }}}" CommandParameter="{Binding}" />


кнопка стала активна, но команда не работает
3)
убрал DataContext из DataGrid и назначил его на уровне Window
Код: xml
1.
2.
3.
4.
    <Window.DataContext >
        <local:ViewModel/>
    </Window.DataContext>
    


привязка команды:
Код: xml
1.
 <Button Content="Х" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type  Window }}}" CommandParameter="{Binding}" />


4)
Код: xml
1.
<Button Content="Х" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:ViewModel}}}" CommandParameter="{Binding}" />


Пробовал
Код: vbnet
1.
    Public Shared ReadOnly DeleteCommandProperty As DependencyProperty = DependencyProperty.Register("DeleteCommand", GetType(ICommand), GetType(MainWindow), New PropertyMetadata(Nothing))



заменить на
Код: vbnet
1.
    Public Shared ReadOnly DeleteCommandProperty As DependencyProperty = DependencyProperty.Register("DeleteCommand", GetType(ICommand), GetType(ViewModel), New PropertyMetadata(Nothing))



Ни в каком случае команда не срабатывает.
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39355208
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наконец нашел время, чтобы взглянуть подробнее..

Ошибка в том, что вы пытаетесь получить свойство не из VM, а из некоторого объекта визуального дерева.

Вот так, например, будет работать:
Код: xml
1.
<Button Content="Х" Command="{Binding Path=DataContext.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding}" />



Правда, это довольно негибкий подход, жесткая привязка к месту привязки DataContext, жесткое ограничение структуры формы.
Пару месяцев тут уже было обсуждение именно такого случая, Роман давал рецепт, попробуйте найти.

ЗЫ: Код вы привели не весь, пришлось переводить частично с C#, спотыкаясь на незнакомом синтаксисе. Приводите уж полностью... или бросайте это дела, переходите на шарп ))
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39355210
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39355959
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
используйте RoutedCommand, они дают большую гибкость.
Есть 1 минус, для MVVM нужно делать свой обработчик маршрутизируемых команд, который можно будет связывать с моделью представления, я сегодня дома, так что скинуть не смогу его.
Суть простая, в любом месте (ячейки грида, строка списка) вы добавляете элемент управления с командой (обычно это кнопка или любой другой элемент наследуемый ICommandSource) и задаете свойству Command ранее определенную в стат. классе марш. команду.
Команда это работает на RoutedEvents типа Bubble, всплывает к корню дерева, и на нужном уровне можно её перехватит и обработать.
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39356557
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
спасибо за помощь - заработало. В следующий раз буду дублировать код на на C#. Понимаю, что Basic зло для WPF, но пока всилу привычки не могу полностью перейти на C#.
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39356558
vb_sub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Roman Mejtes, скиньте посмотреть, когда будет возможность плиз
...
Рейтинг: 0 / 0
DataGrid с кнопкой в строке
    #39356630
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vb_subRoman Mejtes, скиньте посмотреть, когда будет возможность плиз
http://rgho.st/8cJJdkdRK
пример, правда старый, я его уже кидал его в этом разделе, но ссылка сдохла, я обновил
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / DataGrid с кнопкой в строке
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]