Selecting the item in TileView

11 posts, 1 answers
  1. Goran
    Goran avatar
    77 posts
    Member since:
    Feb 2011

    Posted 21 Jun 2012 Link to this post

    Hi,

    I am trying to use TIleView in a simple way, as you can see below. I just need to stack each item (label) according to the number of columns that I set, and allow user to select one item in it.

    <telerik:RadTileView Grid.Column="1"
           ColumnsCount="5"
           ColumnWidth="*"
           ContentTemplate="{StaticResource tileContentTemplate}"
           IsItemDraggingEnabled="False"
           IsSelectionEnabled="True"
           IsSynchronizedWithCurrentItem="True"
           ItemsSource="{Binding List}"
           ItemTemplate="{StaticResource tileHeaderTemplate}"
           MaximizeMode="Zero"
           RowHeight="140"
           SelectedItem="{Binding SelectedItem}" />


    Problems:

    1) When items are loaded, and I want to select a particular item, I need to click twice on it: one time to select the TileView itself, and another time to select an item. It is expected to be able to select an item by only clicking once. I cannot just put focus on the tiles, since there are some other controls on this view that also can have focus.
    2) If I click somewhere on the TileView space that is not occupied by items, currently selected item will be deselected. I would like to disable this behavior
    3) If I click on a selected item, it will be deselected. I would like to disable this behavior

    Regards,
    Goran
  2. Lancelot
    Lancelot avatar
    251 posts
    Member since:
    Jul 2012

    Posted 22 Jun 2012 Link to this post

    Hi Goran,

    Have you considered using RadDocking and having these interactive "tiles" inside RadPanes? That way you can not only have multiple UI elements in a pane, but you can group them too. They're easily added and removed programmaticlaly at run time as well.

    If you were looking for the visual appearance of RadTile, you could easily style the panes or set the theme to match.

    Lancelot
  3. UI for WPF is Visual Studio 2017 Ready
  4. Goran
    Goran avatar
    77 posts
    Member since:
    Feb 2011

    Posted 22 Jun 2012 Link to this post

    Hi, Lancelot,

    I am not sure if I understand what you mean. I have attached an image that explains what I need. Basically I need to display labels that contain some info about an entity (ex Customer code and name). A user will scroll through labels and select a particular customer and close the view.

    I found TileView does nice job visually of displaying labels. The only problem is the selection part. If you think I do the same with other control, I am willing to listen to any advice.

    Regards,
    Goran
  5. Lancelot
    Lancelot avatar
    251 posts
    Member since:
    Jul 2012

    Posted 22 Jun 2012 Link to this post

    Goram,

    If I understand your goal correctly, I think you would be best off with a RadGridView in a child window and when the user selects the item, you can close the child window. RadGridView will let you display all the items you want in any column/row format you want.

    Your mock-up hints at you just simply want a few columns and as many rows as there are customers. RadGridView is perfect for this. When the user selects the label they want, you can close the window and pass the item along in a SelectionChanged event.

    This example demonstrates a click event that fires off for a selection (the link brings you to the online Silverlight version, but the WPF version is the same). While you're there, drop down the little box that says "Other GridView Examples". You can choose from a myriad of examples to see the RadGridView's flexibility.


    Good Luck,
    Lancelot
  6. Goran
    Goran avatar
    77 posts
    Member since:
    Feb 2011

    Posted 22 Jun 2012 Link to this post

    Hi Lancelot,

    I am not sure if GridView is capable of displaying labels. If you look at the image I have attached, you can see that there are 3 labels in one row, which means that GridView would need to display three customers in one row, and allow acustomer to be selected (not row).

    Regards,
    Goran
  7. Lancelot
    Lancelot avatar
    251 posts
    Member since:
    Jul 2012

    Posted 22 Jun 2012 Link to this post

    You can definitely create your own row style. You'd be creating your own style and each column would be a different label (in your example you have shipping an return labels), and you would be doing cell selection instead of row selection. So for the customer they'd have which ever label youd need next to them and selecting the proper label would be a cell selection. I know its not an exact match to what you mocked up, but you have the option to make it look like by using custom row styling.

    Here is an example of custom row styling that contains many labels inside one cell. Then  you'd be passing off the cell selection after the click event, and inside that cell is your custom data template.

    You'd only have to make the template once and set as a resource for the GridView, A style for return label and a style for shipping labels. This link shows how you can conditionally apply cell styling depending on a value.

    Lancelot
  8. Goran
    Goran avatar
    77 posts
    Member since:
    Feb 2011

    Posted 22 Jun 2012 Link to this post

    The image with labels is something that I took from web, and is not directly related to what I want to achieve (its quite ugly). :)

    If you look at my 2nd post where I tried to explain better, I say:

    "Basically I need to display labels that contain some info about an entity (ex Customer code and name). A user will scroll through labels and select a particular customer and close the view."

    So, one label will be one customer, where customer name and customer code is displayed. There can be 4-5-6.... labels in one row, depending of the size of the view and the size of the label. Just look at the first or second example for TileView, and you will see what I am after - each label is a separate entity.

    What you are showing me so far, is just creating a custom template for a row, but with GridView it is always: one entity = one row, which I do not want.

    Regards,
    Goran
  9. Answer
    Lancelot
    Lancelot avatar
    251 posts
    Member since:
    Jul 2012

    Posted 26 Jun 2012 Link to this post

    Hi Goran,

    I believe I have a solution that will work for you using RadlistBox and also using RadTileView. Using the UniformGrid, you can get the results you're looking for. Also, there is a way to customize the RadTileView to achieve the results you want.

    Below is the MainWindow.xaml and MainWindow.cs file contents. There are two other files in the application one is the ViewModel, and the other is a simple class for the setter of MyItem.

    First lets start with MainWindow.xaml.  This contains both RadListBox and RadTileView bound to the same items to demonstrate which one you'd prefer. Paste this into your RootGrid of the main window:
    <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <telerik:RadTileView x:Name="tileView"
                                 ColumnsCount="5"
                                 ColumnWidth="*"
                                 IsItemDraggingEnabled="False"
                                 IsSelectionEnabled="True"
                                 IsSynchronizedWithCurrentItem="True"
                                 ItemsSource="{Binding Items}"
                                 MaximizeMode="Zero"
                                 PreviewMouseLeftButtonUp="tileView_PreviewMouseLeftButtonUp"
                                 RowHeight="140"
                                 SelectedItem="{Binding SelectedItem,
                                                        Mode=TwoWay}"
                                 SelectionMode="Extended">
                <telerik:RadTileView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" />
                    </DataTemplate>
                </telerik:RadTileView.ItemTemplate>
                <telerik:RadTileView.ContentTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="Content of:" />
                            <TextBlock Foreground="Blue" Text="{Binding Name}" />
                        </StackPanel>
                    </DataTemplate>
                </telerik:RadTileView.ContentTemplate>
            </telerik:RadTileView>
            <telerik:RadListBox Grid.Column="1" ItemsSource="{Binding Items}">
                <telerik:RadListBox.Style>
                    <Style TargetType="telerik:RadListBox">
                        <Setter Property="ItemsPanel">
                            <Setter.Value>
                                <ItemsPanelTemplate>
                                    <UniformGrid></UniformGrid>
                                </ItemsPanelTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </telerik:RadListBox.Style>
                <telerik:RadListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="Content of:" />
                            <TextBlock Foreground="Green" Text="{Binding Name}" />
                        </StackPanel>
                    </DataTemplate>
                </telerik:RadListBox.ItemTemplate>
            </telerik:RadListBox>
        </Grid>

    Next here is the MainWindow.xaml.cs file. This contains logic for the MouseLeftButtonUp event, you can determine what you need you application to do in here with your selected item. Paste this into your MainWindow.xaml.cs replacing your class.
    public partial class MainWindow : Window
        {
            private List<DependencyObject> visualHits;
            public MainWindow()
            {
                InitializeComponent();
     
                this.DataContext = new ViewModel();
            }
     
            private void tileView_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                this.visualHits = new List<DependencyObject>();
                var pt = e.GetPosition(this);
                VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(this.MyHitTestResult), new PointHitTestParameters(pt));
                foreach (var vh in this.visualHits)
                {
                    RadTileViewItem container = vh.ParentOfType<RadTileViewItem>();
                    if (container != null)
                    {
                        return;
                    }
                }
     
                e.Handled = true;
            }
     
            private HitTestResultBehavior MyHitTestResult(HitTestResult result)
            {
                this.visualHits.Add(result.VisualHit);
     
                // Set the behavior to return visuals at all z-order levels.
                return HitTestResultBehavior.Continue;
            }
        }


    Next we need to setup your example ViewModel and MyItem class before running the demo. Add a class named ViewModel.cs and insert this code:
    public class ViewModel : ViewModelBase
        {
            private ObservableCollection<MyItem> items;
            private MyItem selectedItem;
     
            public ViewModel()
            {
                this.items = new ObservableCollection<MyItem>();
     
                for (int i = 0; i < 8; i++)
                {
                    this.items.Add(new MyItem() { Name = "Item " + i });
                }
            }
     
            public MyItem SelectedItem
            {
                get
                {
                    return this.selectedItem;
                }
                set
                {
                    if (this.selectedItem != value)
                    {
                        this.selectedItem = value;
                        this.OnPropertyChanged("SelectedItem");
                    }
                }
            }
     
            public ObservableCollection<MyItem> Items
            {
                get
                {
                    return this.items;
                }
                set
                {
                    this.items = value;
                }
            }
        }

    Now create a new class named MyItem.cs and insert this code

    public class MyItem
        {
            public string Name { get; set; }
        }

    Now that we have everything in place, build it and then deploy. I hope this helps you determine which route you want to take.

    Good Luck,
    Lancelot
  10. Goran
    Goran avatar
    77 posts
    Member since:
    Feb 2011

    Posted 28 Jun 2012 Link to this post

    Hi Lancelot,

    thanks for the help you are providing.

    I have looked at your TileView example, and it solves the problem with unselecting. There was a minor problem that now user can select multiple items, but with a few more lines of code I was able to solve that and simulate Single selection mode.

    Thanks for the info for UniformGrid.

    Regards,
    Goran
  11. Priyalakshmi
    Priyalakshmi avatar
    12 posts
    Member since:
    Jul 2012

    Posted 15 Oct 2012 Link to this post

    Hi friends,

    In my wpf application, the requirement was that we should avoid menu but at the same time we need to have it. So I used TileView for this purpose. But the problem now is that the client want to open up the page on click of the image that is being displayed on the tile rather than the small maximize button. Is it possible to achieve that? Is there anyway in which I can maximize the page by clicking on the tile image rather than the maximize icon?

    Thanks in advance
    Priya 
  12. Zarko
    Admin
    Zarko avatar
    755 posts

    Posted 17 Oct 2012 Link to this post

    Hi,
    There are two ways to maximize a RadTileView item:
    - you could use our ToggleTileState command
    - you can do this in code-behind in some event handler
    To use the command you will need an element that have a command like RadButton and in code-behind you can do it for any element. Could you please try this code:
    xmlns:tileView="clr-namespace:Telerik.Windows.Controls.TileView;assembly=Telerik.Windows.Controls.Navigation"
    ....
    <telerik:RadTileView MinimizedColumnWidth="250">
    <telerik:RadTileViewItem>
    <telerik:RadTileViewItem.Header>
    <Image Width="30"
    Height="25"
    MouseLeftButtonDown="OnImageMouseLeftButtonDown"
    Source="Images/strawberry.png" />
    </telerik:RadTileViewItem.Header>
    </telerik:RadTileViewItem>
    <telerik:RadTileViewItem>
    <telerik:RadTileViewItem.Header>
    <telerik:RadButton Command="tileView:TileViewCommands.ToggleTileState" Content="Some content" />
    </telerik:RadTileViewItem.Header>
    </telerik:RadTileViewItem>
    </telerik:RadTileView>
    and
    private void OnImageMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var image = sender as FrameworkElement;
        if (image == null)
            return;
     
        var container = image.ParentOfType<RadTileViewItem>();
        if (container != null)
        {
            if (container.TileState != TileViewItemState.Maximized)
                container.TileState = TileViewItemState.Maximized;
            else
                container.TileState = TileViewItemState.Restored;
        }
    }
    If you have further questions please feel free to ask.

    Regards,
    Zarko
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top
UI for WPF is Visual Studio 2017 Ready