ListBox Item do not render in result image when created programatically

2 posts, 0 answers
  1. Tim
    Tim avatar
    19 posts
    Member since:
    Dec 2011

    Posted 31 Oct 2013 Link to this post

    I have a page when a user can configure a secondary live tile. This page renders an instance of a user control to present a 'preview' on what their tile will look like. The user control takes a ViewModel instance after being constructed, which is then set as the data context. 

    UserControl
    It takes a size enum, and based on the size, resizes the layout root to render different tile image sizes for later.
    public partial class ucLiveTile : UserControl
        {
            public LiveTileViewModel ViewModel { get; set; }
     
            #region Dependency Properties
     
            public enum Size
            {
                Small,
                Medium,
                Large
            }
     
            public static readonly DependencyProperty TileSizeProperty =
                DependencyProperty.Register("TileSize", typeof (Size), typeof (ucLiveTile), new PropertyMetadata(default(Size)));
     
            public Size TileSize
            {
                get { return (Size) GetValue(TileSizeProperty); }
                set { SetValue(TileSizeProperty, value); }
            }
             
            #endregion
     
            public ucLiveTile()
            {
                InitializeComponent();
                Loaded += (sender, args) => InitializeSize();
            }
     
            private void InitializeSize()
            {
                System.Windows.Size size;
                switch (TileSize)
                {
                    case Size.Small:
                        size = new System.Windows.Size(159, 159);
                        LayoutRoot.Width = 159;
                        LayoutRoot.Height = 159;
                        break;
                    case Size.Medium:
                        size = new System.Windows.Size(336, 336);
                        LayoutRoot.Width = 336;
                        LayoutRoot.Height = 336;
                        break;
                    case Size.Large:
                        size = new System.Windows.Size(691, 336);
                        LayoutRoot.Width = 691;
                        LayoutRoot.Height = 336;
                        break;
                    default:
                        size = new System.Windows.Size(336, 336);
                        LayoutRoot.Width = 336;
                        LayoutRoot.Height = 336;
                        break;
                }
     
                Measure(size);
                Arrange(new Rect(new Point(), size));
            }
     
            public void SetData(LiveTileViewModel viewModel)
            {
                ViewModel = viewModel;
                ViewModel.RefreshSettings();
                // create a color off of the config so we can set the background
                var color = Color.FromArgb((byte)ViewModel.TileConfig.BackgroundResourceColor[0],
                                           (byte)ViewModel.TileConfig.BackgroundResourceColor[1],
                                           (byte)ViewModel.TileConfig.BackgroundResourceColor[2],
                                           (byte)ViewModel.TileConfig.BackgroundResourceColor[3]);
     
                ViewModel.BackgroundColor = new SolidColorBrush(color);
                DataContext = ViewModel;

                InvalidateArrange();
                UpdateLayout();

            }
        }

    From the configuration page, I create an instance of the control, and add it to the page:
    void LiveTile_Loaded(object sender, RoutedEventArgs e)
    {
          // removed unrelated code
     
        // create the tile control and add to the page
        _ucLiveTile = new ucLiveTile {TileSize = ucLiveTile.Size.Medium};
        _ucLiveTile.SetData(_viewModel);
        spTile.Children.Add(_ucLiveTile);
    }

    When I see the page, the user control renders exactly like I'd expect it to. The problem lies in trying to do this completely via code, say in a background worker, where I need to instantiate this user control and create an image.

    Creating the instances programatically
    public static bool CreateOrUpdateTile(BudgetLiveTileConfig config)
    {
        // create a view model instance to populate the control
        var viewModel = new LiveTileViewModel(config.Budget.UniqueId);
     
        // Create the tiles
        var smallTile = new ucLiveTile {TileSize = ucLiveTile.Size.Small};
        smallTile.SetData(viewModel);
     
        var mediumTile = new ucLiveTile {TileSize = ucLiveTile.Size.Medium};
        mediumTile.SetData(viewModel);
                 
        var wideTile = new ucLiveTile {TileSize = ucLiveTile.Size.Large};
        wideTile.SetData(viewModel);
     
        // tile data
        var data = new RadFlipTileData()
        {
            SmallVisualElement = smallTile,
            VisualElement = mediumTile,
            WideVisualElement = wideTile
        };
     
        // tile navigation uri
        var budgetUri = new Uri("/Views/BudgetDetail.xaml?b=" + config.Budget.UniqueId, UriKind.Relative);
                 
        // check for an existing tile
        var exists = ShellTile.ActiveTiles.FirstOrDefault(t => t.NavigationUri == budgetUri);
     
        // pin the tile
        LiveTileHelper.CreateOrUpdateTile(data, budgetUri, true);
     
        return exists != null;
    }

    The issue is that the ListBox in the user control DOES NOT render the list items. I've verified the data source is correct by trying to bind a simple textbox to the Categories data source. I've also tried setting the background of the ListBox to a random color, just to prove to me that the list is actually rendering in the tile. However, the problem seems to lie in that the list items are not rendered. 

    I've tried alternating between ListBox & RadDataBoundListBox and the effect is the same. The only difference is that the RadDataBoundListBox shows the EmptyContent message, even when there is a dataset.
  2. Todor
    Admin
    Todor avatar
    778 posts

    Posted 01 Nov 2013 Link to this post

    Hi Tim,

    Thank you for writing.

    The reason for this behavior is that by the time the tile is rendered, the data binding is not yet evaluated. You have two options here: either use the 'preview feature'  and create a tile based on the rendered control, or remove the data binding from the user control and set the properties of the elements explicitely.

    I hope this information helps. Let us know if you need further assistance.
     

    Regards,
    Todor
    Telerik
    Have a suggestion or face a problem - you can use the Ideas & Feedback portal to submit ideas, feedback and vote for them.
  3. DevCraft banner
Back to Top