WP7: problemas de enlace con UserControl
Frecuentes
Visto 554 veces
0
A medida que desarrollo mi aplicación, descubro que estoy recreando un control de "mosaico" con demasiada frecuencia. Por lo tanto, actualmente estoy tratando de moverlo a un Control de usuario para volver a usarlo. Sin embargo, actualmente no acepta ningún enlace que funcionaba anteriormente. Así por ejemplo:
<Canvas Height="73" Width="73" VerticalAlignment="Top" Margin="10,10,8,0">
<Rectangle Height="73" Width="73" VerticalAlignment="Top" Fill="{Binding Path=Active, Converter={StaticResource IconBackground}}" />
<Image Height="61" Width="61" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="6" Source="{Binding Tone.Image}" />
</Canvas>
Funciona bien con las fijaciones,
<views:Tile Height="73" Width="73" Background="{Binding Path=Active, Converter={StaticResource IconBackground}, Mode=OneWay}" Icon="{Binding Path=Tone.Image, Mode=OneTime}" />
produce el error "el parámetro es incorrecto".
Aquí está el código para mi Tile UserControl:
Mosaico.xaml
<UserControl x:Class="RSS_Alarm.Views.Tile"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="100" d:DesignWidth="100">
<Grid x:Name="LayoutRoot">
<Canvas Height="100" Width="100" Margin="0,0,0,0">
<Rectangle Name="rectBackground" Height="100" Width="100" />
<Image Name="imgIcon" Height="80" Width="80" VerticalAlignment="Center" HorizontalAlignment="Center" Canvas.Left="10" Canvas.Top="10" />
</Canvas>
</Grid>
</UserControl>
Tile.xaml.cs
namespace RSS_Alarm.Views
{
public partial class Tile : UserControl
{
public Tile()
{
InitializeComponent();
}
public String Icon
{
get
{
return imgIcon.Source.ToString();
}
set
{
BitmapImage alarmIcon = new BitmapImage();
alarmIcon.UriSource = new Uri(value, UriKind.Relative);
imgIcon.Source = alarmIcon;
}
}
new public Brush Background
{
get
{
return rectBackground.Fill;
}
set
{
rectBackground.Fill = value;
}
}
new public double Height
{
get
{
return rectBackground.Height;
}
set
{
rectBackground.Height = value;
imgIcon.Height = value * 0.8;
}
}
new public double Width
{
get
{
return rectBackground.Width;
}
set
{
rectBackground.Width = value;
imgIcon.Width = value * 0.8;
}
}
}
}
Si necesita alguna fuente más, hágamelo saber y lo publicaré. No tengo ningún problema cuando uso un valor fijo (Height
y Width
están bien, y si pongo Background
a Red entonces eso también funciona bien), pero cambiar a un valor Binding arroja la excepción.
EDIT 1
Aquí hay un código actualizado:
Tile.xaml.cs
#region Background
public static readonly DependencyProperty RectBackgroundProperty =
DependencyProperty.Register(
"RectBackground",
typeof(SolidColorBrush),
typeof(Tile),
new PropertyMetadata(new SolidColorBrush(Colors.Green), new PropertyChangedCallback(OnBackgroundChanged))
);
public static void OnBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("Filling background");
((Tile)d).rectBackground.Fill = (Brush)e.NewValue;
}
new public SolidColorBrush Background
{
get { return (SolidColorBrush)GetValue(RectBackgroundProperty); }
set {
Debug.WriteLine("Setting colour");
SetValue(RectBackgroundProperty, value);
}
}
#endregion
MainMenuControl.xaml.cs
// Class to determine the background colour of the icon (active/inactive)
public class IconBackground : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool b = (bool)value;
Debug.WriteLine("Converting colour. Value is " + b.ToString());
if (b)
{
return (Brush)App.Current.Resources["PhoneAccentBrush"];
}
else
{
return new SolidColorBrush(Colors.DarkGray);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush brush = (SolidColorBrush)value;
if (brush.Color.Equals(Colors.DarkGray))
{
return false;
}
else
{
return true;
}
}
}
También estoy comparando los dos métodos uno al lado del otro. El mosaico de la izquierda es el lienzo definido con enlaces en pleno funcionamiento, mientras que el mosaico de la derecha es el control de usuario de mosaico, que solo funciona con colores definidos (azul en este caso)
1 Respuestas
2
Para poder enlazar en XAML no basta con crear una propiedad. Tienes que crear un DependenciaPropiedad.
La razón por la que tu Background
obras vinculantes, es que UserControl
tiene esta propiedad. Si establece un punto de interrupción en su Background
setter de propiedad, verás que nunca se llama.
Aquí hay un ejemplo de un DependencyProperty
para su Background
(no probado)
#region Background
public const string BackgroundPropertyName = "Background";
public new Brush Background
{
get { return (Background)GetValue (BackgroundProperty); }
set { SetValue (Background, value); }
}
public static new readonly DependencyProperty BackgroundProperty = DependencyProperty.Register (
BackgroundPropertyName,
typeof (Brush),
typeof (Tile),
new PropertyMetadata (BackgroundChanged));
static void BackgroundChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Tile) d).rectBackground = (Brush)e.NewValue;
}
#endregion
contestado el 23 de mayo de 17 a las 13:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c# windows-phone-7 user-controls or haz tu propia pregunta.
¿Algún tutorial que puedas recomendar sobre esto? Mis intentos de implementar esto han llegado a nada hasta ahora. - Michael Dodd
vea la edición, para las otras propiedades solo tiene que cambiar los nombres y tipos - pulgarcitos
Ha funcionado para el Icono. Todavía estoy tratando de hacerlo funcionar con el fondo. - Michael Dodd
para el fondo, realmente no lo necesita, ya que el control de usuario tiene esta propiedad de todos modos. Simplemente elimine rectBackground de su xaml - pulgarcitos
Eliminar rectBackground y usar la propiedad de fondo integrada de UserControl no funciona. Curiosamente, si cambio el nombre de la propiedad a TileBG y uso un color definido, el método rectBackground funciona bien. Sin embargo, todavía se cae al encuadernarlo. Ver Edición 1 para mi código actual. - Michael Dodd