我正在开发一个从UserControl派生的图表控件,一切都很好,直到我发现无法通过绑定设置底轴的DependencyProperty为止。这是图表控件的代码片段:

  public class AxisBase : FrameworkElement
    {
        public IList<double> ExtraGridLines
        {
            get { return (IList<double>)GetValue(ExtraGridLinesProperty); }
            set { SetValue(ExtraGridLinesProperty, value); }
        }
        public static readonly DependencyProperty ExtraGridLinesProperty =
            DependencyProperty.Register("ExtraGridLines", typeof(IList<double>), typeof(AxisBase), new PropertyMetadata(null, OnExtraGridLineDataPropertyChanged));
        private static void OnExtraGridLineDataPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //Problem: data bing would not work, and
            //this call back method will never get called!
            Debug.WriteLine("ExtraGridLines changed...");
        }
    }

    public sealed partial class MyChart : UserControl
    {
        public MyChart()
        {
            this.InitializeComponent();
        }

        public AxisBase BottomAxis
        {
            get { return (AxisBase)GetValue(BottomAxisProperty); }
            set { SetValue(BottomAxisProperty, value); }
        }
        public static readonly DependencyProperty BottomAxisProperty =
            DependencyProperty.Register("BottomAxis", typeof(AxisBase), typeof(MyChart), new PropertyMetadata(null));


    }


这是绑定代码:

<Page x:Class="App1.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App1"
      x:Name="rootPage">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <local:MyChart>
            <local:MyChart.BottomAxis>
                <local:AxisBase ExtraGridLines="{Binding MyExtraGridLines, ElementName=rootPage}" />
            </local:MyChart.BottomAxis>
        </local:MyChart>
    </Grid>
</Page>


public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    private List<double> _myExtraGridLines;
    public List<double> MyExtraGridLines
    {
        get { return _myExtraGridLines; }
        set
        {
            _myExtraGridLines = value;
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyExtraGridLines"));
        }
    }

    public MainPage()
    {
        this.InitializeComponent();
        this.MyExtraGridLines = new List<double>() { 10, 100, 1000 };
    }

    public event PropertyChangedEventHandler PropertyChanged;
}


问题是:绑定似乎永远不会起作用,dp ExtraGridLines的PropertyChangedCallback方法永远不会被调用。但是,这些代码在WPF中有效。我的代码有什么问题?还是一个错误?
任何想法将不胜感激!

编辑1:
这似乎与数据类型无关,即使我将类型从IList<double>更改为intstringobject,问题也是一样。但是,如果将AxisBase的类型从FrameworkElement更改为DependencyObject,则绑定将起作用。但是此解决方案是不可接受的,因为DependencyObject没有Style

编辑2:
最后,我想我已经找到了ElementName绑定不起作用的原因:ElementName绑定仅适用于同一NameScope中的元素。如果您有兴趣,请参阅以下两个很好的链接以获取更多信息:
https://stackoverflow.com/questions/18389118/how-does-binding-elementname-work-exactly
http://www.cnblogs.com/idior/archive/2010/05/28/1746513.html

顺便说一句:一开始我是错的:这些代码在WPF中也不起作用。绑定将引发运行时错误:
System.Windows.Data错误:4:找不到引用'ElementName = rootPage'的绑定源。 BindingExpression:Path = ShowAxisLabel; DataItem = null;目标元素是'AxisBase'(Name ='');目标属性为“ IsLabelVisible”(类型为“布尔”)

顺便说一句2:若要使DataContext绑定在上面的代码中起作用,AxisBase应侦听MyChart的DataContext的更改,或显式添加到MyChart的Logical或Visual树中。那是我代码的错误。但是由于NameScope问题,在这里似乎没有正常或优雅的方法来绑定ElementName。

也许我应该将此问题的标题更改为:为什么在UserControl中绑定到UserControl中的Element的ElementName在UWP / WPF中不起作用?

最佳答案

这很可能是UWP中传统绑定的错误;但是,对于新的x:Bind,以下代码应该可以正常工作。

<local:AxisBase ExtraGridLines="{x:Bind MyExtraGridLines, Mode=OneWay}" />

请注意,这也可以提供更好的性能。因此,您应该始终考虑首先使用这种绑定方法。

更新资料

看起来真正的问题与ElementName与祖先的绑定有关。但是,如果您通过这样指定DataContext来使用普通的MVVM方法,

MyExtraGridLines = new List<double>() { 10, 100, 1000 };

DataContext = this;


并删除与普通的ElementName绑定-

<local:AxisBase ExtraGridLines="{Binding MyExtraGridLines}" />


另外,通过添加-来确保axis元素在视觉树中

<UserControl x:Class="xxx.MyChart">
    <Grid>
        <ContentPresenter Content="{x:Bind BottomAxis, Mode=OneWay}" />
    </Grid>
</UserControl>


这也应该起作用。

关于c# - UWP错误?绑定(bind)到某些嵌套的DependencyProperty不能正常工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44612644/

10-11 15:20
查看更多