WPF: фрейм для получения данных в ItemsControl - PullRequest
0 голосов
/ 06 августа 2020

Мне нужна часть моего Page неподвижного объекта, поэтому я решил использовать Frame, что-то вроде:

<StackPanel>
     <Label Style="{StaticResource OneThirdColumnLabel}">Administrar papéis: Alterar papéis</Label>
         <ItemsControl x:Name="PapeisIc">
             <ItemsControl.ItemTemplate>
                 <DataTemplate>
                      <Frame x:Name="_papeisAddFrame" Source="PapeisAdd.xaml" Height="50"/>
                  </DataTemplate>
              </ItemsControl.ItemTemplate>
          </ItemsControl>
</StackPanel>

Тогда Frame будет содержать Page с:

<ScrollViewer VerticalScrollBarVisibility="Visible">
    <StackPanel>
        <StackPanel Orientation="Horizontal" Margin="0,0,0,10">
            <Label Style="{StaticResource LaterLabel}">Papel:</Label>
            <TextBox Text="{Binding Papel}" Style="{StaticResource StdTextBox}" Width="100" />
            <Label Style="{StaticResource LaterLabel}">Descrição:</Label>
            <TextBox Text="{Binding Descricao}" Style="{StaticResource StdTextBox}" Width="400" />
            <Button x:Name="DeleteFieldBtn" Style="{StaticResource deleteFieldButtom}" ToolTip="Eliminar este papel"/>
        </StackPanel>
    </StackPanel>
</ScrollViewer>

В коде программной части строка:

PapeisIc.ItemsSource = _papeis;

Привязывает объект, который является ObservableCollection из 3 элементов, и мне нужно, чтобы он отображал 3 элемента в примере.

Я получаю:

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

Так что каким-то образом он знает, что есть 3 элемента, но не связывает его правильно ...

Я уже пытался передать Page данные в качестве параметра , но это тоже не сработало.

Как я могу связать эти значения?

Чтобы было понятно, я пытаюсь привязать к ObservableCollection из:

public class Role
{
    public int Id { get; set; }
    public string Papel { get; set; }
    public string Descricao { get; set; }
}

1 Ответ

1 голос
/ 06 августа 2020

Элемент управления Frame не передает DataContext вниз Page. Самый простой способ решить эту проблему - удалить Frame и переместить его содержимое непосредственно в DataTemplate.

Если вам действительно нужен Frame, вы должны прослушать LoadCompleted и DataContextChanged и вручную передать DataContext содержимое Frame. Я покажу вам, как это сделать с помощью TriggerAction, используя Microsoft.Xaml.Behaviors.Wpf пакет NuGet.

public class UpdateContentDataContextAction : TriggerAction<Frame>
{
   protected override void Invoke(object parameter)
   {
      if (AssociatedObject.Content is FrameworkElement frameworkElement)
         frameworkElement.DataContext = AssociatedObject.DataContext;
   }
}
<DataTemplate>
   <Frame x:Name="_papeisAddFrame" Source="PapeisAdd.xaml" Height="50">
      <b:Interaction.Triggers>
         <b:EventTrigger EventName="LoadCompleted">
            <local:UpdateContentDataContextAction/>
         </b:EventTrigger>
         <b:EventTrigger EventName="DataContextChanged">
            <local:UpdateContentDataContextAction/>
         </b:EventTrigger>
      </b:Interaction.Triggers>
   </Frame>
</DataTemplate>

Если вы хотите сделать это в коде программной части, подпишитесь на события в элементе управления и используйте код срабатывания триггера.

<Frame x:Name="_papeisAddFrame" Source="PapeisAdd.xaml" Height="50" LoadCompleted="OnLoadCompleted" DataContextChanged="OnDataContextChanged">
private void OnLoadCompleted(object sender, NavigationEventArgs e)
{
   PropagateDataContext((Frame)sender);
}

private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
   PropagateDataContext((Frame)sender);
}

private void PropagateDataContext(Frame frame)
{
   if (frame.Content is FrameworkElement frameworkElement)
      frameworkElement.DataContext = frame.DataContext;
}
...