【问题标题】:How to set selected area in Listbox如何在列表框中设置选定区域
【发布时间】:2014-01-23 08:51:17
【问题描述】:

我需要这样做:

它是带有元素的自定义 DataTemplate 的列表框。 (我将列表的整个元素都画了绿色。)

现在我有了这个:

如果它是真实的 - 如何更改我的 DataTemplate(或 Listbox 样式)以获得第一个结果? (以某种方式设置选定区域)

数据模板

<DataTemplate x:Key="TrackDataTemplate">
    <Grid Margin="0,-5,0,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="{Binding FirstPlatformName}" Grid.Row="0" Grid.Column="0"/>
        <Path x:Name="Node"
            Margin="10,0" Grid.Row="0" Grid.Column="1"
            Data="M3.1999443,36.501999 L47.300057,36.501999 47.292366,36.517475 C43.192585,44.521747 34.86105,50 25.25,50 15.638952,50 7.3074172,44.521747 3.2076359,36.517475 z M25.25,0.5 C38.919049,0.49999976 50,11.580952 50,25.25 50,27.599367 49.672657,29.87228 49.061096,32.025615 L48.919384,32.501999 1.5806161,32.501999 1.438906,32.025615 C0.82734287,29.87228 0.5000003,27.599367 0.5,25.25 0.5000003,11.580952 11.580953,0.49999976 25.25,0.5 z"
            Fill="{DynamicResource white75}" Stretch="Fill"
            Width="17"  Height="17"/>
        <Rectangle x:Name="Connection" Grid.Row="1" Grid.Column="1"
            HorizontalAlignment="Center" VerticalAlignment="Top"
            Fill="{DynamicResource white75}"  Height="17" Width="4" Margin="10,2,10,0"/>
        <TextBlock Grid.Row="1" Grid.Column="2" TextWrapping="Wrap"
            Text="{Binding TsAndChannelNumber}"/>
    </Grid>
</DataTemplate>

列表框

<ListBox Grid.Column="1"
    SelectedItem="{Binding SelectedTrackSegment}"
    ItemsSource="{Binding SelectedTrack.Segments}"
    ItemTemplate="{StaticResource TrackDataTemplate}"
    Margin="30,20,30,0"/>

【问题讨论】:

  • 介意添加数据模板吗?
  • 添加了DataTemplate代码
  • datatemplate 似乎是正确的,只是项目被完全选中,这就是为什么你没有以你想要的方式得到它。只需尝试在网格第 0 行和第 2 列上添加一个透明矩形
  • 感谢您的想法!但是如果你谈论类似的东西 这是行不通的,但如果使用不透明的颜色一切效果很好 稍后我将在答案中编写工作版本

标签: wpf xaml datatemplate


【解决方案1】:

为了完全控制 ListBoxItem,您可能需要更改 ItemContainerStyle 中的模板。 这是一个小测试项目来说明我的意思。 请注意,我在文本块周围添加了 2 个网格,以便可以使用触发器更改背景属性。

Xaml

 <ListBox x:Name="MyList">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Grid Margin="0,-5,0,0">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="70"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>

                                <Grid x:Name="PlatformGrid">
                                    <TextBlock Text="{Binding FirstPlatformName}" />
                                </Grid>
                                <Path x:Name="Node"
                                                Margin="10,0" Grid.Row="0" Grid.Column="1"
                                                Data="M3.1999443,36.501999 L47.300057,36.501999 47.292366,36.517475 C43.192585,44.521747 34.86105,50 25.25,50 15.638952,50 7.3074172,44.521747 3.2076359,36.517475 z M25.25,0.5 C38.919049,0.49999976 50,11.580952 50,25.25 50,27.599367 49.672657,29.87228 49.061096,32.025615 L48.919384,32.501999 1.5806161,32.501999 1.438906,32.025615 C0.82734287,29.87228 0.5000003,27.599367 0.5,25.25 0.5000003,11.580952 11.580953,0.49999976 25.25,0.5 z"
                                                Fill="Blue" Stretch="Fill" 
                                                Width="17"  Height="17"/>

                                <Rectangle x:Name="Connection" Grid.Row="1" Grid.Column="1" 
                                                HorizontalAlignment="Center" VerticalAlignment="Top"
                                                Fill="Blue"  Height="17" Width="4" Margin="10,2,10,0"/>
                                <Grid x:Name="TSGrid" Grid.Row="1" Grid.Column="2">
                                    <TextBlock  TextWrapping="Wrap" Text="{Binding TsAndChannelNumber}"/>
                                </Grid>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                        <Condition Property="IsSelected" Value="True"/>
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Background" TargetName="PlatformGrid" Value="Red"/>
                                    <Setter Property="Background" TargetName="TSGrid" Value="Red"/>
                                </MultiTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>

MainWindows.cs

public MainWindow()
    {
        InitializeComponent();

        Loaded += (s, args) =>
            {
                this.DataContext = this;
                MyList.ItemsSource = LoadSegments();
            };
    }

    private static List<Segment> LoadSegments()
    {
        var segments = new List<Segment>
        {
            new Segment { FirstPlatformName = "FPName01", TsAndChannelNumber = "TSNumber0(ChannelNumber0" },
            new Segment { FirstPlatformName = "FPName01", TsAndChannelNumber = "TSNumber0(ChannelNumber1" },
            new Segment { FirstPlatformName = "FPName01", TsAndChannelNumber = "TSNumber0(ChannelNumber2" },
            new Segment { FirstPlatformName = "FPName01", TsAndChannelNumber = "TSNumber0(ChannelNumber3" },
            new Segment { FirstPlatformName = "FPName01", TsAndChannelNumber = "TSNumber0(ChannelNumber4" }
        };
        return segments;
    }

Segment.cs

public class Segment
{
    public string FirstPlatformName { get; set; }
    public string TsAndChannelNumber { get; set; }
}

理想情况下,您需要在 Blend 中“编辑 ItemContainerStyle 模板的副本”,这样您就可以访问所有标准行为,然后像上面那样编辑 Trigger IsSelected 希望对你有帮助

【讨论】:

  • 非常感谢! 这段代码真的帮了我
【解决方案2】:

但我建议使用两个 ListBox 并使用 IsSynchronizedWithCurrentItem 属性为 true。所以当你选择一个时,它会自动选择另一个相同的项目。您可以为每个列表框定义自己的数据模板。

【讨论】:

    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多