This question is locked. New answers and comments are not allowed.
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.
From the configuration page, I create an instance of the control, and add it to the page:
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
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.
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.