【问题标题】:wpf custom control get/set not firingwpf自定义控件获取/设置不触发
【发布时间】:2012-06-19 22:34:46
【问题描述】:

我正在学习 WPF,并且来自 Flex 和 AS,有时它似乎过于复杂。抛开意见不谈,我的问题如下。

我创建了一个自定义控件 ToolBarButton,它基本上是一个注定要包含在自定义工具栏中的图像按钮。我已经向这个控件添加了一些属性,我希望能够从 XAML 中设置它们。尽管该属性出现在 XAML 端的 AutoCompletion 中,但从未触发 Set 方法并且该属性保持为空。所以这里是 ToolBarButton 背后的代码:

    public static readonly DependencyProperty ImgSrcProperty = DependencyProperty.RegisterAttached("ImgSource", typeof(string), typeof(ToolBarButton));

    public static readonly DependencyProperty OnClickProperty = DependencyProperty.Register("OnClick", typeof(RoutedEventHandler), typeof(ToolBarButton));

    public ToolBarButton(RoutedEventHandler OnClick, string imgSrc, Map map = null, string ConfigFile = null) :
        base(ConfigFile, map)
    {
        if (OnClick != null) SetValue(OnClickProperty, OnClick);

        if (imgSrc != null) SetValue(ImgSrcProperty, imgSrc);

        this.AddChild(CreateButton());

        InitializeComponent();
    }

    public ToolBarButton() : this(null, null) { }

    private Button CreateButton()
    {
        BitmapImage icon = new BitmapImage();
        icon.BeginInit();
        icon.UriSource = new Uri(ImgSource, UriKind.Relative);
        icon.EndInit();

        Image img = new Image();
        img.Stretch = Stretch.Fill;
        img.Source = icon;

        Button BtnToAdd = new Button();
        BtnToAdd.Width = 35;
        BtnToAdd.Height = 35;
        BtnToAdd.Content = img;
        BtnToAdd.Background = new ImageBrush(icon);

        BtnToAdd.Click += OnClick;

        return BtnToAdd;
    }


    public string ImgSource
    {
        get { return (string)GetValue(ImgSrcProperty); }
        set { SetValue(ImgSrcProperty, value); }
    }

    public RoutedEventHandler OnClick
    {
        get { return (RoutedEventHandler)GetValue(OnClickProperty); }
        set { SetValue(OnClickProperty, value); }
    }

您会注意到两个构造函数,一个用于在运行时创建控件,另一个用于从 XAML 创建它。

这是使用自定义控件但不触发 set 方法的 XAML 代码:

<BaseControls:ToolBar 
         x:Class="Basic_Mapping.Widgets.NavigationToolBar"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:BaseControls="clr-namespace:Basic_Mapping.Base_Controls"
         mc:Ignorable="d" >

<BaseControls:ToolBarButton Width="35" Height="35" ImgSource="Assets/i_zoomin.png"  ConfigFileName="ZoomIn.xml" />

任何帮助将不胜感激!

吉尔曼

编辑:

这是用于 ToolBarButton 的基类,它的属性也有同样的问题。

public partial class ConfigurableUserControl : UserControl
{
    private XmlDocument configXML;

    public static readonly DependencyProperty XmlProperty = DependencyProperty.Register("ConfigFileName", typeof(string), typeof(ConfigurableUserControl));

    public static readonly DependencyProperty MapProperty = DependencyProperty.Register("Map", typeof(Map), typeof(ConfigurableUserControl));

    public ConfigurableUserControl(string configFile, Map map)
    {
        if (configFile != null) SetValue(XmlProperty, configFile);

        if (map != null) SetValue(MapProperty, map);

        string file = (string)GetValue(XmlProperty);

        if (file != null)
        {
            configXML = new XmlDocument();

            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\Config\\" + configFile);

            if (File.Exists(path)) configXML.Load(path);
        }
    }

    public ConfigurableUserControl() : this(null, null) { }

    public string ConfigFileName
    {
        //get { return (string)GetValue(XmlProperty); }
        set { SetValue(XmlProperty, value); }
    }

    public Map Map
    {
        get { return (Map)GetValue(MapProperty); }
        set { SetValue(MapProperty, value); }
    }

    public XmlDocument ConfigXML
    {
        get { return configXML; }
    }
}

【问题讨论】:

  • 您的 ImgSrcProperty 是一个附加属性,它不应该是。你能列出这个派生的基类吗?您可以添加一个 OnPropertyChanged 事件以查看该 get 是否被触发(它应该),因为 DependecyProperties 的 getter 和 setter 并不总是在某些调试/编译设置下触发。
  • 我忘了说我也尝试过在公共变量上使用基本的 get/set 属性,但它没有帮助。我将编辑原始帖子以显示基类

标签: c# wpf xaml custom-controls


【解决方案1】:

我的猜测是,这个问题以及您对基类的问题是由于您没有实现 INotifyPropertyChanged 并进行适当的调用。

【讨论】:

  • 确实,我没有实现 INotifyPropertyChanged,我会进一步研究。
  • 好吧,看来我已经成功了,现在我只需要弄清楚调用的顺序。似乎在设置属性之前调用了构造函数......我想我必须向 InitializationComplete 或其他东西添加一个事件侦听器。无论如何,感谢您帮助解决问题!
  • 似乎我还不能发布和更新答案,因为我是新用户。我会尽量记住明天发布。
【解决方案2】:

尝试将InitializeComponent(); 放在构造函数的开头,而不是当前所在的末尾。

【讨论】:

  • 我忘了指出,set 方法可能不会被触发,因为 XAML 可以直接调用依赖对象方法 GetValueSetValue
  • 这只是为了回答您关于未调用 setter 的部分问题。它对其余部分没有帮助。
  • 我想知道你的基类是否也应该在其构造函数中调用 InitializeComponent。
  • 它不允许我调用InitializeComponent,我认为这个方法只适用于Xaml文件不是吗?
  • 对不起,我只是假设有一个用于用户控件的 XAML 文件,如果没有,则不需要它。
猜你喜欢
  • 2013-04-04
  • 2013-04-13
  • 1970-01-01
  • 2011-01-23
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 2020-06-03
相关资源
最近更新 更多