【问题标题】:Which Control will be more appropriate to the output shown below?哪个控件更适合下面显示的输出?
【发布时间】:2014-03-06 03:58:57
【问题描述】:

在我对数据库和代码进行一些更改之前,我的项目运行良好。

更改前:

输出:

Tile1    Tile7    ..........    Tile(N-x)
Tile2    Tile8                  Tile(N-x+1)
Tile3    Tile9                  ....
Tile4    Tile10                 ....
Tile5    Tile11                 ....
Tile6    Tile12                 Tile(N)

数据库中的表: 1------- [主键] 标题 | 背景 | 图片 | ParentID *------- [外键]

XAML:

<ListBox Grid.Row="1" x:Name="lst"
         ItemsSource="{Binding ChildrenMenus}" >

    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel IsItemsHost="True" Orientation="Vertical" MaxHeight="{Binding ElementName=lst, Path=ActualHeight}"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Width" Value="250" />
            <Setter Property="Height" Value="125" />
            <Setter Property="Margin" Value="2.5" />
            <Setter Property="Padding" Value="2.5" />
            <Setter Property="Background" Value="{Binding Background, Converter={StaticResource stringToBrushConverter}}" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="VerticalContentAlignment" Value="Bottom" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Foreground" Value="{Binding Background, Converter ={StaticResource stringToBrushConverter}}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.Resources>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Height="125" Width="250">
                <Path Data="{Binding Image}"  VerticalAlignment="Center" 
                      Stretch="Uniform" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"
                      Width="68" Height="68" Margin="10" RenderTransformOrigin="0.5,0.5">
                    <Path.RenderTransform>
                        <TransformGroup>
                            <TransformGroup.Children>
                                <RotateTransform Angle="0" />
                                <ScaleTransform ScaleX="1" ScaleY="1" />
                            </TransformGroup.Children>
                        </TransformGroup>
                    </Path.RenderTransform>
                </Path>
                <TextBlock Text="{Binding Title, Converter={StaticResource spaceToNewLineConverter}}" VerticalAlignment="Top" 
                           Margin="40,10,10,10" FontSize="24" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>

</ListBox>

目前:

所需输出:

Text1     Text2            Text3             ..........     Text(N)

Tile1     Tile3  Tile7     Tile9    Tile13                  Tile(N-x)        .....
Tile2     Tile4  Tile8     Tile10                           Tile(N-x + 1)    .....
          Tile5            Tile11                           ....             .....
          Tile6            Tile12                           ....             Tile(N)

数据库变化:

我在 ViewModel 和 XAML 文件中尝试了许多更改,现在它搞砸了。所以,如果我发布这些代码,那么它对任何人都没有用。

我希望我已经正确地提到了所有问题。

更新

首先我很抱歉。我的互联网连接一整天都中断了。我刚刚看了你的留言。

现在,我得到了一些东西。我可以从 Design_Master_MenuItems 的数据库中获取数据。见下图:

但绑定仍然无法正常工作。我的意思是我的 ItemsControl 中的 ListBoxes 没有被填充。

这是我当前的 XAML:

<ItemsControl ItemsSource="{Binding MenuCategories}" >

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True" Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid >
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>

                <TextBlock Text="{Binding Title}" FontSize="30" />

                <ListBox Grid.Row="1" x:Name="lst"
                         ItemsSource="{Binding Design_Master_TileItems}" DisplayMemberPath="Title">

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

这是我的视图模型:

public class MainWindowViewModel : ViewModelBase
{

    public MainWindowViewModel()
    {
        using (Entities db = new Entities())
        {
            ParentMenus = new ObservableCollection<Design_Master_ParentMenus>(from d in db.Design_Master_ParentMenus select d);

            if (SelectedParent != null)
                MenuCategories = new ObservableCollection<Design_Master_Categories>(from d in db.Design_Master_Categories
                                                                                  where d.ParentMenuID == SelectedParent.ParentMenuID 
                                                                                  select d);
        }
    }

    private ObservableCollection<Design_Master_ParentMenus> _parentMenus;
    public ObservableCollection<Design_Master_ParentMenus> ParentMenus
    {
        get
        {
            return _parentMenus;
        }
        set
        {
            _parentMenus = value;
            OnPropertyChanged("ParentMenus");
        }
    }

    private Design_Master_ParentMenus _selectedParent;
    public Design_Master_ParentMenus SelectedParent
    {
        get
        {
            return _selectedParent;
        }
        set
        {
            _selectedParent = value;
            OnPropertyChanged("SelectedParent");

            using (Entities db = new Entities())
            {
                MenuCategories = new ObservableCollection<Design_Master_Categories>(from d in db.Design_Master_Categories
                                                                                  where d.ParentMenuID == SelectedParent.ParentMenuID
                                                                                  select d);
            }
        }
    }

    private ObservableCollection<Design_Master_Categories> _menuCategories;
    public ObservableCollection<Design_Master_Categories> MenuCategories
    {
        get
        {
            return _menuCategories;
        }
        set
        {
            _menuCategories = value;
            OnPropertyChanged("MenuCategories");
        }
    }

}

是的,我在接下来的 10 个小时内都没有空。如果您在上面的代码中发现任何错误,您可以发表评论。感谢您的大力帮助。

更新2

是的,现在我在输出窗口中发现绑定错误:

System.Windows.Data Error: 17 : Cannot get 'Design_Master_TileItem' value (type 'ICollection`1') from '' 
(type 'Design_Master_Catego_79D2EFE4D31EC6575261E40C340C9D078D37C022F94C70A5F8A88A9017957C24').     
BindingExpression:Path=Design_Master_TileItem; 
DataItem='Design_Master_Catego_79D2EFE4D31EC6575261E40C340C9D078D37C022F94C70A5F8A88A9017957C24' 
(HashCode=28842409); target element is 'ListBox' (Name=''); target property is 'ItemsSource' (type 
'IEnumerable') TargetInvocationException:'System.Reflection.TargetInvocationException: Property accessor 
'Design_Master_TileItem' on object
'System.Data.Entity.DynamicProxies.Design_Master_Catego_79D2EFE4D31EC6575261E40C340C9D078D37C022F94C70A5F8A8
8A9017957C24' threw the following exception:'The ObjectContext instance has been disposed and can no     
longer be used for operations that require a connection.' ---> System.ObjectDisposedException: The 
ObjectContext instance has been disposed and can no longer be used for operations that require a 
connection.

System.Windows.Data Error: 17 : Cannot get 'Design_Master_TileItem' value (type 'ICollection`1') from '' 
(type 'Design_Master_Catego_79D2EFE4D31EC6575261E40C340C9D078D37C022F94C70A5F8A88A9017957C24'). 
BindingExpression:Path=Design_Master_TileItem; 
DataItem='Design_Master_Catego_79D2EFE4D31EC6575261E40C340C9D078D37C022F94C70A5F8A88A9017957C24' 
(HashCode=13006057); target element is 'ListBox' (Name=''); target property is 'ItemsSource' (type 
'IEnumerable') TargetInvocationException:'System.Reflection.TargetInvocationException: Property accessor 
'Design_Master_TileItem' on object 
'System.Data.Entity.DynamicProxies.Design_Master_Catego_79D2EFE4D31EC6575261E40C340C9D078D37C022F94C70A5F8A8    
8A9017957C24' threw the following exception:'The ObjectContext instance has been disposed and can no 
longer be used for operations that require a connection.' ---> System.ObjectDisposedException: The     
ObjectContext instance has been disposed and can no longer be used for operations that require a       
connection.

【问题讨论】:

  • 您是在询问使用哪个 WPF 控件进行显示吗?
  • +1 包含很多细节,只是缺少您正在寻求帮助的确切内容。
  • @LordTakkera 是的,你完全正确。我在问哪种容器最适合这种情况,如果可以的话,请提供一个例子。
  • 我没有发现任何明显的错误。您的输出窗口中是否出现任何数据绑定异常?除列表框外,“大”块是否正确显示?它是否适用于数据网格或列表视图?
  • 你可以在这里下载示例项目:drive.google.com/file/d/0B5WyqSALui0bM05BSVRia2VCcFk/…

标签: c# wpf xaml


【解决方案1】:

首先,您需要一个带有水平 StackPanel 的 ListView 作为面板模板来获取您的“大”块。

然后,对于每个块,您需要一个“标题”,然后是另一个 ListView,这次使用垂直 WrapPanel 作为面板模板。下面是一个“shell”示例,需要一些样式和绑定才能使其看起来完全符合您的要求,但希望它能让您走上正确的道路。

<ListView>
   <ListView.ItemsPanel>
       <ItemsPanelTemplate>
           <StackPanel Orientation="Horizontal"></StackPanel>
       </ItemsPanelTemplate>
   </ListView.ItemsPanel>
   <ListView.ItemTemplate>
       <DataTemplate>
           <StackPanel>
               <TextBlock/>
               <ListView>
                   <ListView.ItemPanelTemplate>
                       <WrapPanel Orientation="Vertical"></WrapPanel>
                   </ListView.ItemPanelTemplate>
                   <ListView.ItemTemplate>
                       <DataTemplate>
                           <TextBlock/>
                       </DataTemplate>
                   </ListView.ItemTemplate>
               <ListView>
           </StackPanel>
       </DataTemplate>
   </ListView.ItemTemplate>
<ListView>

更新:

要只有“一个选择”,请确保选择任一列表框都会调用属性上的设置器。我通常不使用 RelativeSource 来执行此操作,因此如果您想尝试一下,这里有一个示例(您的窗口/用户控件名为“Root”:

"{Binding ElemantName=Root, Path=DataContext.SelectedTileItem}" 

转换器要做到这一点会变得非常复杂。这个answer 有一种可接受的方式来设置你想要做的事情,这可能是你想要的方式(我会使用组名路线,因为这基本上是你想要做的)。

【讨论】:

  • 这是一个很好的答案。现在我对你的回答有两个问题。 (1) 制作大块的第一个 Listview 将允许我选择一个块。但我不需要选择。还有(2)为什么我应该使用 ListView 而不是 ListBox 来创建图块?我应该说谢谢你的回答。谢谢。
  • 我相信 ListBox 也能正常工作,我只是习惯使用 ListView。如果您确实想沿着这条路线走,有几种方法可以使 ListViews 无法选择。如果你使用 ListBox,我很想知道它是否基本相同,或者我是否忘记了一些问题。
  • 另外一个问题是我应该只能从任何内部 ListView 中选择一个项目。我的意思是如果我有两个 ListView。在每个 ListView 内我有 1 个 ListView。所以我应该只能从第一个列表视图或第二个列表视图中选择 1 个项目。而且当我使用键盘的箭头键时,我应该很舒服。我的意思是,如果我在第一个内部 ListView 上按右箭头,那么如果当前选定项目右侧的第一个内部列表视图中有任何项目,那么应该选择它,否则焦点应该转到第二个内部 ListView 项目的相应项目.
  • 我使用了 ItemsControl 而不是 ListBox。所以我第一条评论中的问题就解决了。
  • 为了完成“只选择一个”的要求,我会将所有列表框的选定项属性绑定到同一个 VM 属性并使用“ValueEqualsConverter”的变体:stackoverflow.com/a/2908885/1783619
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 2011-05-01
  • 2012-06-29
  • 1970-01-01
  • 2011-03-10
相关资源
最近更新 更多