0

Есть ItemsControl, если в его DataTemplate посетить разметку все работает отлично.

Привязка данных:

<UserControl.DataContext>
    <ViewModel:LogCollectionViewModel/>
</UserControl.DataContext>

Сам ItemsControl:

<ItemsControl ItemsSource="{Binding AllJournal.AllEvents}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border Margin="0 0 2.5 2.5" Height="200"
        Width="300">
                <Grid>

                    <Grid.RowDefinitions>
                        <RowDefinition Height="25"/>
                        <RowDefinition Height="175"/>
                    </Grid.RowDefinitions>

                    <Rectangle Grid.Row="0"
                   Grid.RowSpan="2"
                   Fill="White"
                   Opacity="0.5"/>

                    <Grid Grid.Row="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100"/>
                            <ColumnDefinition Width="75"/>
                            <ColumnDefinition Width="125"/>
                        </Grid.ColumnDefinitions>

                        <TextBlock Grid.Column="0"
                       Grid.Row="0"
                       Text="{Binding RecordNo}"
                       Style="{StaticResource TextBlockMainStyle}"/>

                        <TextBlock Grid.Column="1"
                       Grid.Row="0"
                       Text="{Binding Time}"
                       ToolTip="Время события"
                       Style="{StaticResource TextBlockMainStyle}"/>

                        <TextBlock Grid.Column="2"
                       Grid.Row="0"
                       Text="{Binding Date}"
                       ToolTip="Дата события"
                       Style="{StaticResource TextBlockMainStyle}"/>

                    </Grid>

                    <local:SignalEventView Grid.Row="1"/>

                </Grid>
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Но если весь код из DataTemplate вынести в отдельный UserControl и в DataTemplate добавить только ссылку на этот UserControl, то все перестает работать.

Пример:

<ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:LogEventView/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

Разметка LogEventView:

<UserControl.DataContext>
    <ViewModel:LogEventVM/>
</UserControl.DataContext>

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/Styles/LogEventStyle.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

<Border Margin="0 0 2.5 2.5" Height="200"
        Width="300">
    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="25"/>
            <RowDefinition Height="175"/>
        </Grid.RowDefinitions>

        <Rectangle Grid.Row="0"
                   Grid.RowSpan="2"
                   Fill="White"
                   Opacity="0.5"/>

        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <TextBlock Grid.Column="0"
                       Grid.Row="0"
                       Text="{Binding RecordNo}"
                       Style="{StaticResource TextBlockMainStyle}"/>

            <TextBlock Grid.Column="1"
                       Grid.Row="0"
                       Text="{Binding Time}"
                       ToolTip="Время события"
                       Style="{StaticResource TextBlockMainStyle}"/>

            <TextBlock Grid.Column="2"
                       Grid.Row="0"
                       Text="{Binding Date}"
                       ToolTip="Дата события"
                       Style="{StaticResource TextBlockMainStyle}"/>

        </Grid>

        <local:SignalEventView Grid.Row="1"/>

    </Grid>
</Border>

Скриншоты:

Если разметка напрямую в DataTemplate:

введите сюда описание изображения

Если в DataTemplate вставить <local:LogEventView/>, то появляется только количество событий, но с нулевыми данными:

введите сюда описание изображения

Как решить данный вопрос? Так как разметки будет очень много, и оставлять все о одном UserControl не целесобразно.

  • Что значит все перестает работать? – Андрей NOP Feb 01 '18 at 12:43
  • @АндрейNOP при обновлении коллекции создается правильное количество экземпляров, но они пустые, без данных, просто отрисованы. – UporotayaPanda Feb 01 '18 at 12:50

1 Answers1

1

Проблема в этом:

<UserControl.DataContext>
    <ViewModel:LogCollectionViewModel/>
</UserControl.DataContext>

Контрол никогда не имеет права устанавливать себе ViewModel, хуже того — создавать её. Уберите это, должно по идее работать.

VladD
  • 206,799
  • а как тогда привязать данные? Как контрол поймет откуда брать данные? – UporotayaPanda Feb 01 '18 at 12:38
  • Если убрать этот код, то коллекция не обновляется... – UporotayaPanda Feb 01 '18 at 12:40
  • А контролу должны эти данные дать снаружи. Откуда он знает, какой именно экземпляр ему нужен? – VladD Feb 01 '18 at 12:41
  • «то коллекция не обновляется» — а можно подробнее? Что вы делаете и что происходит. – VladD Feb 01 '18 at 12:42
  • ItemsControl содержит список событий журнала. Для этих событий есть отдельная ViewModel - LogEventView, которая привязана к LogEventVM (привязывал так же, как и в самом вопросе, только к LogEventVM ). ItemsControl находится внутри LogCollectionView. Если в DataTemplate вставить просто ссылку на LogEventView, то коллекция обновляется и показывает количество событий, но сами события "пустые". Если же вставить разметку напрямую, все работает отлично. – UporotayaPanda Feb 01 '18 at 12:43
  • @UporotayaPanda: Угу, а всё же что вы делаете, что происходит, и что вы хотели бы, чтобы происходило? – VladD Feb 01 '18 at 12:44
  • если отвязать привязку данных, то коллекция не обновляется вообще. – UporotayaPanda Feb 01 '18 at 12:48
  • А вы передаёте снаружи данные в ваш внешний UserControl? (Я правильно угадал, у вас их два?) – VladD Feb 01 '18 at 12:59
  • спасибо большое, вы были правы! Нужно отвязать данные, но видимо я не так все объяснил сначала, данные нужно отвязывать во вложенном UserControl! Благодарю за помощь! – UporotayaPanda Feb 01 '18 at 12:59
  • @UporotayaPanda: Пожалуйста! Но мне кажется, данные правильнее передавать предавать снаружи и во внешний UserControl тоже. Подумайте, это обычно правильный подход. – VladD Feb 01 '18 at 13:02
  • а можете скинуть ссылку на правильную реализацию? А то в разных источниках и примерах все по своему делают... – UporotayaPanda Feb 01 '18 at 13:03
  • На мой вкус, правильно так: (1) Окно получает от создающего кода корневую VM (https://ru.stackoverflow.com/a/562586/10105). (2) Вложенные контролы получают VM как Binding к свойствам корневой VM. – VladD Feb 01 '18 at 13:06