Vishal
Vishal

Reputation: 6368

Which Control will be more appropriate to the output shown below?

My project was working good before I made some changes in my database and my code.

Before Changes :

Output :

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

Table in Database: 1------- [Primary Key] Title | Background | Image | ParentID *------- [Foreign Key]

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>

Currently:

Required Output:

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)

Changes in database:

enter image description here

I have tried many changes in ViewModel and XAML files and now it got messed up. So, if I post those codes then also it will not be useful to anybody.

I hope I have mentioned everything correctly in question.

Update

First of all I am sorry. My internet connection was down for the whole day. I have read your messages just now.

Now, I have got something. I can get data from database in Design_Master_MenuItems. See the Image below:

enter image description here

But still Binding does not work correctly. I mean my ListBoxes inside ItemsControl are not being populated.

Here is my current 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>

Here is myViewModel :

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");
        }
    }

}

Yes, and I will not be available for next 10 hours. If you find any mistake in the above code you may comment. Thanks for a big helping hand.

Update2

Yes now I find the binding error in Output window:

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.

Upvotes: 1

Views: 233

Answers (1)

BradleyDotNET
BradleyDotNET

Reputation: 61339

First you want a ListView with a horizontal StackPanel as the panel template to get your "big" blocks.

Then, for each block, you'll need a "header" and then another ListView, this time with a vertical WrapPanel as the panel template. Below is a "shell" example that would need some styling and bindings to get it to look exactly the way you want, but hopefully it gets you on the right track.

<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>

Update:

To have only "one selection", make sure that selecting either list box calls the setter on your property. I normally don't do this with RelativeSource, so here is an example if you want to try it (where your window/user control is named "Root":

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

A converter is going to get really complicated to do this. This answer has an accepted way of setting up what you are trying to do, and it is probably the way you want to go (I would use the group name route, since that is basically what you are trying to do).

Upvotes: 1

Related Questions