【问题标题】:WP7: Binding problems with UserControlWP7:用户控件的绑定问题
【发布时间】:2012-05-03 17:51:21
【问题描述】:

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

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

如果您需要更多来源,请告诉我,我会发布。使用固定值时我没有任何问题(HeightWidth 很好,如果我将 Background 设置为红色,那么也可以正常工作),但是更改为 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,它仅适用于定义的颜色(在本例中为蓝色)

【问题讨论】:

    标签: c# windows-phone-7 user-controls


    【解决方案1】:

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

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

    这是一个DependencyProperty 的示例,用于您的Background(未测试)

    #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
    

    【讨论】:

    • 有什么教程可以推荐吗?到目前为止,我实现这一点的尝试都没有结果。
    • 查看编辑,对于其他属性,您只需更改名称和类型
    • 它适用于图标。仍在尝试让它在后台工作。
    • 对于你并不真正需要它的背景,因为用户控件无论如何都有这个属性。只需从您的 xaml 中删除 rectBackground
    • 删除 rectBackground 并使用 UserControl 的内置 Background 属性不起作用。有趣的是,如果我将属性重命名为 TileBG 并使用定义的颜色,那么 rectBackground 方法可以正常工作。然而,它仍然落在绑定上。请参阅编辑 1 了解我当前的代码。
    猜你喜欢
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2011-04-07
    • 2010-12-15
    相关资源
    最近更新 更多