Reputation: 19353
I have a XAML UserControl
which defines a fairly basic button - I want to define a Bindable property HasMeasurements
which will display an overlay image when HasMeasurements
is false . However when I include it in my project and bind it to the ViewModel it does not update consistently.
I am sure the ViewModel is properly notifying the bindings since I have simultenously bound the same ViewModel property to another separate element and it updates as expected. Also it works in Blend when I update the mock data.
I have tried this solution which defines a callback where I change the Visibility programatically, however this callback is not called every time the ViewModel property changes, only sometimes. I have also tried binding the Visibility in the XAML using this solution and a non dependency property which also did not work. I have also tried implementing NotifyPropertyChanged
out of desperation but no luck there either ...
Here is my XAML,
<UserControl x:Class="MyApp.View.Controls.ConversionBtn"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid x:Name="btnGrid" toolkit:TiltEffect.IsTiltEnabled="True" Height="115">
<Border Background="{StaticResource ImgOverlayColor}" BorderThickness="0" Padding="0" VerticalAlignment="Top" >
<TextBlock x:Name="titleTxtBlock" FontSize="{StaticResource PhoneFontSizeMedium}" Foreground="{StaticResource TileTxtColor}" Margin="6,0,0,0"/>
</Border>
<Image x:Name="notAvailableImg" Source="/Images/ConversionNotAvailableOverlay.png" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None" />
</Grid>
</Grid>
</UserControl>
Here is the code behind,
// usings here ...
namespace MyApp.View.Controls
{
public partial class ConversionBtn : UserControl
{
public ConversionBtn()
{
InitializeComponent();
if (!TiltEffect.TiltableItems.Contains(typeof(ConversionBtn)))
TiltEffect.TiltableItems.Add(typeof(ConversionBtn));
//this.DataContext = this;
}
public string Title
{
get { return this.titleTxtBlock.Text; }
set { this.titleTxtBlock.Text = value; }
}
public static readonly DependencyProperty HasMeasurementsProperty =
DependencyProperty.Register("HasMeasurements", typeof(bool), typeof(ConversionBtn),
new PropertyMetadata(false, new PropertyChangedCallback(HasMeasurementsPropertyChanged)));
private static void HasMeasurementsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ConversionBtn cBtn = (ConversionBtn)d;
bool val = (bool)e.NewValue;
if (val)
{
cBtn.notAvailableImg.Visibility = Visibility.Collapsed;
}
else
{
cBtn.notAvailableImg.Visibility = Visibility.Visible;
}
cBtn.HasMeasurements = val;
}
public bool HasMeasurements
{
get { return (bool)GetValue(HasMeasurementsProperty); }
set { SetValue(HasMeasurementsProperty, value); }
}
}
}
Upvotes: 0
Views: 842
Reputation: 19353
Ah damnit, it was a combination of Anton's answer and the fact that I hadn't set my image as 'Content', hence it loaded in Blend but was not present in the deployed app.
Upvotes: 0
Reputation: 9230
You have a callback, that is called after HasMeasurment
propetry was changed.
And in a callback you change it again. So, you have a logical misstake.
If you need to do something with this value - just save it in private field.
private static void HasMeasurementsPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
ConversionBtncBtn = (ConversionBtn)d;
bool val = (bool)e.NewValue;
if (val)
{
cBtn.notAvailableImg.Visibility = Visibility.Collapsed;
}
else
{
cBtn.notAvailableImg.Visibility = Visibility.Visible;
}
cBtn.SetMeasurments(val);
}
private bool measurmentsState;
public void SetMeasurments(bool value)
{
measurmentsState = value;
}
Here you can get free e-Book by Charls Petzold about Windows Phone Development, there is a nice chapter about Dependency Properties.
Upvotes: 1