This is a migrated thread and some comments may be shown as answers.

ListBox Item do not render in result image when created programatically

1 Answer 85 Views
LiveTileHelper
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Tim
Top achievements
Rank 1
Tim asked on 31 Oct 2013, 04:32 PM
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.

1 Answer, 1 is accepted

Sort by
0
Todor
Telerik team
answered on 01 Nov 2013, 01:32 PM
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.
Tags
LiveTileHelper
Asked by
Tim
Top achievements
Rank 1
Answers by
Todor
Telerik team
Share this question
or