0

在开发应用程序时,我发现我经常重新创建“平铺”控件。因此,我目前正在尝试将其移动到用户控件中以供重用。但是,它目前不接受任何以前有效的绑定。例如:

<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>

与绑定工作正常,

<views:Tile Height="73" Width="73" Background="{Binding Path=Active, Converter={StaticResource IconBackground}, Mode=OneWay}" Icon="{Binding Path=Tone.Image, Mode=OneTime}" />

产生错误“参数不正确”。

这是我的 Tile UserControl 的代码:

Tile.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;
            }
        }
    }
}

如果您需要更多来源,请告诉我,我会发布。使用固定值时我没有任何问题(Height并且Width很好,如果我设置Background为 Red 那么也可以正常工作),但是更改为 Binding 值会引发异常。


编辑 1

这是一些更新的代码:

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;
        }
    }

}

我也在并排比较这两种方法。左边的图块是定义的 Canvas,绑定完全工作,而右边的图块是 Tile UserControl,它只适用于定义的颜色(在这种情况下为蓝色)

截屏

4

1 回答 1

2

为了能够在 XAML 中进行绑定,仅仅创建一个属性是不够的。您必须创建一个DependencyProperty

Background您的绑定有效的原因是它UserControl本身具有此属性。如果您在Background属性设置器中设置断点,您将看到它永远不会被调用。

这是DependencyPropertyBackground(未测试)的示例

#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
于 2012-05-03T18:01:29.757 回答