So I'm developing a Windows Phone 8 app with the Caliburn.Micro framework. I'm trying to create a grid where I, at runtime add/remove elements such as TextBlock's at runtime. I've tried a few things to bind my code to the x:Name but nothing has worked so far.
So one of the things i tried was having a placeholder grid in my xaml aka View:
<Grid x:Name="ContentPanel" Margin="0,97,0,0" Grid.RowSpan="2">
</Grid>
And then i my ViewModel i use the following to bind my ContentPanel Grid:
private Grid contentPanel;
public Grid ContentPanel
{
get
{
return contentPanel;
}
set
{
contentPanel = value;
NotifyOfPropertyChange(() => ContentPanel);
}
}
I then created a TextBlock to add to the grid:
TextBlock txt1 = new TextBlock();
txt1.Text = "2005 Products Shipped";
txt1.FontSize = 20;
txt1.FontWeight = FontWeights.Bold;
Grid.SetRow(txt1, 1);
And finally i added the TextBlock to my Grid:
ContentPanel.Children.Add(txt1);
When i run this code ContentPanel
turn out to be equals null
, why is that? Shouldn't Caliburn auto bind ContentPanel x:Name="ContentPanel"
with the property ContentPanel
?
I would appreciate your help in this matter.
My core problem, that i need solved is this: I got a login page in my app where i show some pictures and text loaded from a server. As you can see below this is done with Image and a TextBlock When that server is offline or the wi-fi simply aren't enabled i want to replace this picture+text with a static image. Aka i want to remove the TextBlock from the StackPanel.
The part where i load and show the stuff form my server works great and looks like this in my xaml:
<StackPanel Orientation="Horizontal" Background="White" DataContext="{Binding FeedItemsAnnounce,Mode=TwoWay}" >
<Image delay:LowProfileImageLoader.UriSource="{Binding ImagePath,Mode=TwoWay}" Margin="5" Width="170" Height="138">
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Tap">
<cm:ActionMessage
MethodName="LoadAnnouncement">
<cm:Parameter Value="{Binding Link}"></cm:Parameter>
</cm:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" Width="160" Foreground="Black" FontSize="24" VerticalAlignment="Center" Margin="25,0,0,0"></TextBlock>
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Tap">
<cm:ActionMessage
MethodName="LoadAnnouncement">
<cm:Parameter Value="{Binding Link}"></cm:Parameter>
</cm:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
So when the server is offline/wifi disabled i want to replace that with. so that the TextBlock is no longer there:
<Image delay:LowProfileImageLoader.UriSource="{Binding ImagePath,Mode=TwoWay}" DataContext="{Binding FeedItemsAdvertisement,Mode=TwoWay}" Margin="0,20,0,39" Width="380" Height="128">
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Tap">
<cm:ActionMessage
MethodName="LoadAdvertisement" >
<cm:Parameter Value="{Binding Link}"></cm:Parameter>
</cm:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
Is this even possible? If not what would the best semi-solution be?
EDIT 1: I've managed to setup the flow following the instructions from the accepted answer. But my BooleanToVisibilityConverter
is not called, though my NotifyOfPropertyChange(() => IsConnectionAvailable);
is getting called.
My Property:
private bool _isConnectionAvailable;
public bool IsConnectionAvailable
{
get { return _isConnectionAvailable; }
set
{
if (_isConnectionAvailable != value)
{
_isConnectionAvailable = value;
NotifyOfPropertyChange(() => IsConnectionAvailable);
}
}
}
How i change the bool: This code is called in my constructor for my ViewModel(just as a test to see if it was working):
IsConnectionAvailable = false;
TextBlock (without trigger code cause its the same as previous):
<TextBlock Text="{Binding Title}" Visibility="{Binding IsConnectionAvailable, Converter={StaticResource BoolToVisibility}}" TextWrapping="Wrap" Width="160" Foreground="Black" FontSize="24" VerticalAlignment="Center" Margin="25,0,0,0"></TextBlock>
It's like the Binding IsConnectionAvailable
isn't working because i can change the name IsConnectionAvailable
in my Xaml to anything and my NotifyOfPropertyChange(() => IsConnectionAvailable);
will still be called.
Any ideas?
I can't even do a normal bind Visibility="{Binding Path=IsVisibil,Mode=TwoWay}
to a public Visibility IsVisibil
property. I've done this in other classes, but even this won't work??
EDIT 2: The problem that course the binding not to work, seems to lie somewhere in this code:
<StackPanel Orientation="Horizontal" Background="White" DataContext="{Binding FeedItemsAnnounce,Mode=TwoWay}" >
<Image delay:LowProfileImageLoader.UriSource="{Binding ImagePath,Mode=TwoWay}" Margin="5" Width="170" Height="138">
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Tap">
<cm:ActionMessage
MethodName="LoadAnnouncement">
<cm:Parameter Value="{Binding Link}"></cm:Parameter>
</cm:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<TextBlock Text="{Binding Title}" Visibility="{Binding Path=IsVisibil,Mode=TwoWay}" TextWrapping="Wrap" Width="160" Foreground="Black" FontSize="24" VerticalAlignment="Center" Margin="25,0,0,0"></TextBlock>
<i:Interaction.Triggers>
<i:EventTrigger
EventName="Tap">
<cm:ActionMessage
MethodName="LoadAnnouncement">
<cm:Parameter Value="{Binding Link}"></cm:Parameter>
</cm:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</StackPanel>
Solution to EDIT 1 and 2: I created an x:Name"Root" at the top of my xaml structure. Then changed the binding to:
ElementName=Root, Path=DataContext.IsVisibil
This is needed because the binding to visibility that I'm trying to set is inside another DataContxt.