3

Я хочу получить доступ и изменить FlowDirection из RelativePanel в каждом элементе ListViewItem в DataTemplate. Я попробовал этот точный метод, имел ту же ошибку: How do I access a control inside a XAML DataTemplate? Я попробовал решение при слишком, но я сДоступ к RelativePanel в DataTemplate каждого ListViewItem в ULP ListView Windows 10

_Container = MyFlipView.ItemContainerGenerator.ContainerFromItem(item); 

всегда возвращает нуль, даже если мой item не равно нулю. Я попытался разместить UpdateLayout() перед ним, напрасно. Я постарался поставить ожидание

Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() =>{ } 

вокруг него, но и напрасно, всегда возвращаю null. Это мой код:

<ListView x:Name="MessagesListView"> 
     <ListView.ItemContainerStyle> 
      <Style TargetType="ListViewItem"> 
       <Setter Property="HorizontalAlignment" Value="Stretch"/> 
       <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
      </Style> 
     </ListView.ItemContainerStyle> 
     <ListView.ItemTemplate> 
      <DataTemplate x:DataType="data:Message"> 
       <RelativePanel x:Name="RelativeDataTemplate" Background="White" Margin="10,5,10,5" MaxHeight="115" MinHeight="115" MinWidth="400" HorizontalAlignment="Stretch">       
        <TextBlock x:Name="MessageToBlock" Text="{x:Bind MessageTo}" FontSize="14" TextAlignment="DetectFromContent" Foreground="Black" FontWeight="SemiBold" RelativePanel.RightOf="ImageEllipse" Height="20" Margin="10,30,10,20"/> 
        <TextBlock x:Name="AgentNameBlock" Text="{x:Bind AgentName}" Padding="10,0" TextAlignment="DetectFromContent" RelativePanel.RightOf="ImageEllipse" RelativePanel.Below="MessageToBlock" FontSize="14" Foreground="#2d73b5" FontWeight="SemiBold" Height="20"/> 
        <TextBlock x:Name="MessageDateBlock" Text="{x:Bind MessageDate}" TextAlignment="Right" FontSize="14" Foreground="Black" RelativePanel.AlignVerticalCenterWith="MessageToBlock" RelativePanel.AlignRightWithPanel="True" Height="20" Margin="0,30,20,20"/> 
        <TextBlock x:Name="MessageYearBlock" Text="{x:Bind MessageYear}" TextAlignment="Right" FontSize="14" Foreground="#2d73b5" RelativePanel.AlignVerticalCenterWith="AgentNameBlock" RelativePanel.AlignRightWithPanel="True" Margin="0,0,20,0"/> 
       </RelativePanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 

foreach (var item in myListView.Items) 
       { 

        await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
        { 
         UpdateLayout(); 
         myListView.ScrollIntoView(item); 
         var _Container = myListView.ItemContainerGenerator 
         .ContainerFromItem(item) as FrameworkElement; 
        var _Children = AllChildren(_Container); 

        var _RelativePanel = _Children 
         // only interested in RelativePanel 
         .OfType<RelativePanel>() 
         // only interested in RelativePanel 
         .First(x => x.Name.Equals("RelativeDataTemplate")); 

        // test & set color 
        _RelativePanel.FlowDirection = FlowDirection.RightToLeft; 
        }); 
       } 

public List<Control> AllChildren(DependencyObject parent) 
     { 
      var _List = new List<Control>(); 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
      { 
       var _Child = VisualTreeHelper.GetChild(parent, i); 
       if (_Child is Control) 
        _List.Add(_Child as Control); 
       _List.AddRange(AllChildren(_Child)); 
      } 
      return _List; 
     } 

Любое решение, которое я еще не нашел?

+0

Почему вам нужно получить доступ к 'RelativePanel' в DataTemplate? Вы хотите знать DataContext ListViewItem? –

+0

Нет, мне нужно изменить FlowDirection RelativePanel на RightToLeft, сделав все элементы в ListView flip (так как язык будет меняться с английского на арабский). – yalematta

+0

Так, например, существует «CheckBox», если этот флажок не установлен, он перемещается слева направо, и если этот флажок установлен, он перетекает справа налево? Должен быть триггер, чтобы это произошло, иначе вы можете напрямую определить его в коде xaml, правильно? –

ответ

1

Как мы уже говорили, вы использовали ComboBox для выбора языка (направление потока), так что вы можете использовать связывание данных и конвертер, чтобы сделать это, например:

<Page.Resources> 
    <local:FlowDirectionConverter x:Key="cvt" /> 
</Page.Resources> 

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
    <ListView x:Name="MessagesListView" ItemsSource="{x:Bind messagelist}"> 
     <ListView.ItemContainerStyle> 
      <Style TargetType="ListViewItem"> 
       <Setter Property="HorizontalAlignment" Value="Stretch" /> 
       <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
      </Style> 
     </ListView.ItemContainerStyle> 
     <ListView.ItemTemplate> 
      <DataTemplate x:DataType="local:Message"> 
       <RelativePanel x:Name="RelativeDataTemplate" Background="White" Margin="10,5,10,5" MaxHeight="115" MinHeight="115" MinWidth="400" HorizontalAlignment="Stretch" FlowDirection="{Binding ElementName=comboBox, Path=SelectedItem,Converter={StaticResource cvt}}"> 
        <TextBlock x:Name="MessageToBlock" Text="{x:Bind MessageTo}" FontSize="14" TextAlignment="DetectFromContent" Foreground="Black" FontWeight="SemiBold" Height="20" Margin="10,30,10,20" /> 
        <TextBlock x:Name="AgentNameBlock" Text="{x:Bind AgentName}" Padding="10,0" TextAlignment="DetectFromContent" RelativePanel.Below="MessageToBlock" FontSize="14" Foreground="#2d73b5" FontWeight="SemiBold" Height="20" /> 
        <TextBlock x:Name="MessageDateBlock" Text="{x:Bind MessageDate}" TextAlignment="Right" FontSize="14" Foreground="Black" RelativePanel.AlignVerticalCenterWith="MessageToBlock" RelativePanel.AlignRightWithPanel="True" Height="20" Margin="0,30,20,20" /> 
        <TextBlock x:Name="MessageYearBlock" Text="{x:Bind MessageYear}" TextAlignment="Right" FontSize="14" Foreground="#2d73b5" RelativePanel.AlignVerticalCenterWith="AgentNameBlock" RelativePanel.AlignRightWithPanel="True" Margin="0,0,20,0" /> 
       </RelativePanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 

    <ComboBox x:Name="comboBox" VerticalAlignment="Bottom" ItemsSource="{x:Bind languagelist}"> 
     <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding language}" /> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 
</Grid> 

код позади:

public ObservableCollection<Message> messagelist; 
public ObservableCollection<MyLanguage> languagelist = new ObservableCollection<MyLanguage>(); 

public MainPage() 
{ 
    this.InitializeComponent(); 
    messagelist = new ObservableCollection<Message>(); 
} 

protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
    //add data to messagelist 
    languagelist.Clear(); 
    languagelist.Add(new MyLanguage { language = "English" }); 
    languagelist.Add(new MyLanguage { language = "Arabic" }); 
} 

класс MyLanguage довольно прост:

public class MyLanguage 
{ 
    public string language { get; set; } 
} 

и мой преобразователь подобен это:

public class FlowDirectionConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     if (value != null) 
     { 
      var item = value as MyLanguage; 
      if (item.language == "English") 
       return FlowDirection.LeftToRight; 
      else 
       return FlowDirection.RightToLeft; 
     } 
     return FlowDirection.LeftToRight; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, string language) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Удивительный метод! Спасибо! – yalematta

+0

@LayaleMatta, добро пожаловать! ;) –

Смежные вопросы