XAML 根据列表视图中的选定内容更改控件的可见性

cgvd09ve  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(128)

我有一个ListView,里面有一堆支持多重选择的人。我想让它当一个人通过复选框被选中时,会出现额外的控件-在这种情况下,包含一些TimePicker控件的StackPanel变得可见。
当这个人被隐藏时,StackPanel应该恢复为不可见状态。
x1c 0d1x的数据



当前代码:

XAML:
<ContentDialog.Resources>
<DataTemplate x:Key="ContactListViewTemplate" x:DataType="model:Client">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Ellipse x:Name="Ellipse"
            Grid.RowSpan="2"
            Width ="32"
            Height="32"
            Margin="6"
            VerticalAlignment="Center"
            HorizontalAlignment="Center"
            Fill="{ThemeResource SystemControlBackgroundBaseMediumBrush}"/>
                    <TextBlock Grid.Column="1"
            Text="{x:Bind FirstName}"
            x:Phase="1"
            Style="{ThemeResource BaseTextBlockStyle}"
            Margin="12,6,0,0"/>
                <TextBlock  Grid.Column="1"
            Grid.Row="1"
            Text="{x:Bind LastName}"
            x:Phase="2"
            Style="{ThemeResource BodyTextBlockStyle}"
            Margin="12,0,0,6"/>
        <StackPanel Orientation="Horizontal" x:Name="timePanel" Grid.Column="2" Grid.RowSpan="2" Visibility="Collapsed">
            <TimePicker Header="Start"></TimePicker>
            <TimePicker Header="End"></TimePicker>
        </StackPanel>
    </Grid>
</DataTemplate>
</ContentDialog.Resources>

<ListView x:Name="clientsList" SelectionMode="Multiple" ItemTemplate="{StaticResource ContactListViewTemplate}" SelectionChanged="ClientsList_SelectionChanged" />

字符串
代码隐藏:

private void ClientsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    Debug.WriteLine("called mett " + e.AddedItems.Count);
    var listView= sender as ListView;
    if(e.RemovedItems.Count > 0)
    {
        
    }
    if(e.AddedItems.Count > 0)
    {
        foreach(var item in e.AddedItems)
        {
           ListViewItem myListViewItem = (ListViewItem)item;
           ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListViewItem);
            StackPanel stackPanel = myContentPresenter.ContentTemplate.FindDescendant("timePanel") as StackPanel;
        }
    }
}

8ulbf1ek

8ulbf1ek1#

让我向您展示一种方法,即在timePanel上使用Loaded事件。

private void TimePanel_Loaded(object sender, RoutedEventArgs e)
{
    if (sender is not StackPanel timePanel ||
        timePanel.FindAscendant<ListView>() is not ListView listView ||
        timePanel.DataContext is not object dataContext ||
        listView.ContainerFromItem(dataContext) is not ListViewItem listViewItem)
    {
        return;
    }

    timePanel.SetBinding(
        VisibilityProperty,
        new Binding
        {
            Source = listViewItem,
            Path = new PropertyPath("IsSelected"),
            Mode = BindingMode.OneWay,
            Converter = new TrueToVisibleConverter(),
        });
}

字符串
TrueToVisibleConverter应该是这样的:

public class TrueToVisibleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value is bool boolValue && boolValue is true
            ? Visibility.Visible
            : Visibility.Collapsed;
    }

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


顺便说一句,FindAscendant扩展方法来自CommunityToolkit.WinUI.Extensions NuGet包。

相关问题