首页 文章

带有ObservableCollection的WPF UserControl DependencyProperty没有绑定

提问于
浏览
0

我有一个Line Series Chart的用户控件,并为图表上的项创建了一堆依赖属性; Headers ,x轴标签,数据本身等......数据是KeyValuePair的可观察集合 . 当它在主窗口中时,我的图表工作正常 . 我必须在主窗口上有5个系列图表,所以我认为用户控件是一个很好的解决方案 . 我将xaml复制并粘贴到新的用户控件中 . 我添加了绑定到我想要绑定的所有元素; Headers ,标签,间隔和数据 . 然后我在后面的代码中为所有这个绑定创建了属性,并使用DependencyProperty.Register来确保它们将被传递 . Headers 和标签工作得很好,虽然我在主窗口的xaml中硬编码 . 可观察的集合根本没有约束力 . 我尝试了在这个网站上找到的一堆解决方案(即 - 将ElementName = NameOfUserControl添加到绑定,在主窗口的绑定上添加RelativeSource = UserControl) . 我似乎无法通过这些数据 .

如果我没有在主窗口中添加RelativeSource子句,我会收到此错误:

System.Windows.Data错误:40:BindingExpression路径错误:'disposition'属性not>找到'object'''LineGraph'(Name ='Me')' . BindingExpression:路径= Disposition.WidthData; > DataItem ='LineGraph'(Name ='Me'); target元素是'LineGraph'(Name ='Me'); target> property是'ActualData'(类型'ObservableCollection`1')

我以前遇到过这个问题,我最终放弃了,只是将xaml直接放入我的主窗口,而不是使用用户控件 . 我想弄清楚这一点,以便我可以使用更多的用户控件,而不是在我的主窗口中有1000行的xaml .

这是用户控件xaml:

<UserControl x:Class="Essar.Dispo.UI.UserControls.LineGraph"
         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:toolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" 
         xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
         mc:Ignorable="d" x:Name="Me"
         >
<UserControl.Resources>
    <Style TargetType="datavis:Title" x:Key="GraphTitleStyle">
        <Setter Property="Foreground" Value="Black" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="FontWeight" Value="Bold" />
    </Style>

    <Style TargetType="datavis:Title" x:Key="AxisTitleStyle" BasedOn="{StaticResource GraphTitleStyle}">
        <Setter Property="FontSize" Value="12" />
        <Setter Property="FontWeight" Value="Medium" />
    </Style>

    <Style TargetType="datavis:Legend" x:Key="LegendStyle">
        <Setter Property="Width" Value="0" />
    </Style>

    <Style TargetType="toolkit:AxisLabel" x:Key="AxisLabelStyle">
        <Setter Property="Foreground" Value="Black" />
    </Style>
</UserControl.Resources>
<Grid>
    <toolkit:Chart Name="FinishingMillWidthChart" Title="{Binding MainTitle}" Height="350"
                                       TitleStyle="{StaticResource GraphTitleStyle}"
                                       LegendStyle="{StaticResource LegendStyle}">
        <toolkit:Chart.Axes>
            <toolkit:LinearAxis Orientation="X" Title="{Binding XAxisTitle}" Interval="{Binding XAxisInterval}" ShowGridLines="True" 
                                                    AxisLabelStyle="{StaticResource AxisLabelStyle}" TitleStyle="{StaticResource AxisTitleStyle}" />
            <toolkit:LinearAxis Orientation="Y" Title="{Binding YAxisTitle}" ShowGridLines="True" Interval="{Binding YAxisInterval}" 
                                                    AxisLabelStyle="{StaticResource AxisLabelStyle}" TitleStyle="{StaticResource AxisTitleStyle}" />
        </toolkit:Chart.Axes>
        <toolkit:LineSeries Title="tolerance high" DependentValuePath="Value" IndependentValuePath="Key"
                            ItemsSource="{Binding ToleranceHigh, ElementName=Me}" Visibility="{Binding HighLowVisible}">
            <toolkit:LineSeries.DataPointStyle>
                <Style TargetType="{x:Type toolkit:DataPoint}">
                    <Setter Property="Template" Value="{x:Null}" />
                    <Setter Property="Background" Value="YellowGreen" />
                </Style>
            </toolkit:LineSeries.DataPointStyle>
        </toolkit:LineSeries>
        <toolkit:LineSeries Title="actual" DependentValuePath="Value" IndependentValuePath="Key"
                            ItemsSource="{Binding ActualData, ElementName=Me}">
            <toolkit:LineSeries.DataPointStyle>
                <Style TargetType="{x:Type toolkit:DataPoint}">
                    <Setter Property="Template" Value="{x:Null}" />
                    <Setter Property="Background" Value="Maroon" />
                </Style>
            </toolkit:LineSeries.DataPointStyle>
        </toolkit:LineSeries>
        <toolkit:LineSeries Title="tolerance low" DependentValuePath="Value" IndependentValuePath="Key"
                            ItemsSource="{Binding ToleranceLow, ElementName=Me}" Visibility="{Binding HighLowVisible}">
            <toolkit:LineSeries.DataPointStyle>
                <Style TargetType="{x:Type toolkit:DataPoint}">
                    <Setter Property="Template" Value="{x:Null}" />
                    <Setter Property="Background" Value="DarkCyan" />
                </Style>
            </toolkit:LineSeries.DataPointStyle>
        </toolkit:LineSeries>
    </toolkit:Chart>
</Grid>

这是用户控件背后的代码:

public partial class LineGraph : UserControl
{
    public LineGraph()
    {
        InitializeComponent();
        DataContext = this;
    }

    #region Properties
    public static readonly DependencyProperty MainTitleProperty = DependencyProperty.Register("MainTitle", typeof(string), typeof(LineGraph));
    public string MainTitle
    {
        get { return GetValue(MainTitleProperty).ToString(); }
        set { SetValue(MainTitleProperty, value); }
    }


    public static readonly DependencyProperty XAxisTitleProperty = DependencyProperty.Register("XAxisTitle", typeof(string), typeof(LineGraph));
    public string XAxisTitle
    {
        get { return GetValue(XAxisTitleProperty).ToString(); }
        set { SetValue(XAxisTitleProperty, value); }
    }


    public static readonly DependencyProperty YAxisTitleProperty = DependencyProperty.Register("YAxisTitle", typeof(string), typeof(LineGraph));
    public string YAxisTitle
    {
        get { return GetValue(YAxisTitleProperty).ToString(); }
        set { SetValue(YAxisTitleProperty, value); }
    }


    public static readonly DependencyProperty XAxisIntervalProperty = DependencyProperty.Register("XAxisInterval", typeof(double), typeof(LineGraph));
    public double XAxisInterval
    {
        get { return Common.DoubleParse(GetValue(XAxisIntervalProperty)); }
        set { SetValue(XAxisIntervalProperty, value); }
    }

    public static readonly DependencyProperty YAxisIntervalProperty = DependencyProperty.Register("YAxisInterval", typeof(double), typeof(LineGraph));
    public double YAxisInterval
    {
        get { return Common.DoubleParse(GetValue(YAxisIntervalProperty)); }
        set { SetValue(YAxisIntervalProperty, value); }
    }


    public static readonly DependencyProperty ToleranceHighProperty = DependencyProperty.Register("ToleranceHigh", typeof(ObservableCollection<KeyValuePair<double, double>>), typeof(LineGraph));
    public ObservableCollection<KeyValuePair<double, double>> ToleranceHigh
    {
        get 
        {
            return GetValue(ToleranceHighProperty) as ObservableCollection<KeyValuePair<double, double>>; 
        }
        set { SetValue(ToleranceHighProperty, value); }
    }

    public static readonly DependencyProperty ActualDataProperty = DependencyProperty.Register("ActualData", typeof(ObservableCollection<KeyValuePair<double, double>>), typeof(LineGraph));
    public ObservableCollection<KeyValuePair<double, double>> ActualData
    {
        get
        {
            return GetValue(ActualDataProperty) as ObservableCollection<KeyValuePair<double, double>>;
        }
        set { SetValue(ActualDataProperty, value); }
    }

    public static readonly DependencyProperty ToleranceLowProperty = DependencyProperty.Register("ToleranceLow", typeof(ObservableCollection<KeyValuePair<double, double>>), typeof(LineGraph));
    public ObservableCollection<KeyValuePair<double, double>> ToleranceLow
    {
        get
        {
            return GetValue(ToleranceLowProperty) as ObservableCollection<KeyValuePair<double, double>>;
        }
        set { SetValue(ToleranceLowProperty, value); }
    }

    public Visibility HighLowVisible
    {
        get
        {
            if (ToleranceHigh == null || ToleranceLow == null)
                return Visibility.Hidden;
            return Visibility.Visible;
        }
    }

    #endregion
}

请注意,Common.DoubleParse是我的框架中的一个函数,它执行double.TryParse,真的没什么特别的 .

最后这是我主窗口中的xaml,不确定这是否重要,但图表在tabitem,scrollviewer和dockpanel内 .

<uc:LineGraph MainTitle="finishing mill width" Margin="5"
              XAxisTitle="length (meters)" XAxisInterval="10" 
              YAxisTitle="millimeters" YAxisInterval="15"
              ToleranceHigh="{Binding Disposition.WidthToleranceHigh}"
              ActualData="{Binding Disposition.WidthData}"
              ToleranceLow="{Binding Disposition.WidthToleranceLow}"/>

另外一点,我的MainWindowViewModel有一个名为Disposition的属性,它是另一个具有自己属性的视图模型 . 请记住,当图表位于这个完全相同的位置但完整写出时,它可以完美地工作 . 我想我在主窗口或用户控件中缺少一些愚蠢的东西 .

任何帮助表示赞赏:-)

1 回答

  • 0

    永远不要将usercontrol的datacontext设置为此!所以只需删除你的线路 .

    public LineGraph()
    {
        InitializeComponent();
    }
    

    现在当然你应该为你的所有绑定添加你的元素名称,例如 .

    <toolkit:LinearAxis Orientation="X" 
                 Title="{Binding XAxisTitle, ElementName=Me}" 
                 Interval="{Binding XAxisInterval, ElementName=Me}" 
                 ShowGridLines="True" AxisLabelStyle="{StaticResource AxisLabelStyle}" TitleStyle="{StaticResource AxisTitleStyle}" />
    

    编辑:你可以尝试这个代码只是为了看到你的收藏工作的绑定吗?

    <UserControl x:Class="Essar.Dispo.UI.UserControls.LineGraph"
         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:toolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" 
         xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
         mc:Ignorable="d" x:Name="Me"
         >
    <Grid>
    <ItemsControl ItemsSource="{Binding Path=ActualData, ElementName=Me}"/>
    </Grid>
    

    并在您的主视图中添加以下内容

    <uc:LineGraph MainTitle="finishing mill width" Margin="5"
              XAxisTitle="length (meters)" XAxisInterval="10" 
              YAxisTitle="millimeters" YAxisInterval="15"
              ToleranceHigh="{Binding Disposition.WidthToleranceHigh}"
              ActualData="{Binding Disposition.WidthData}"
              ToleranceLow="{Binding Disposition.WidthToleranceLow}"/>
    <ItemsControl ItemsSource="{Binding Disposition.WidthData}"/>
    

    两个itemscontrols应该显示相同 .

    顺便说一句,你可以在运行时检查你的绑定SNOOP

相关问题