【问题标题】:custom user control binding on itemspaneltemplateitemspaneltemplate上的自定义用户控件绑定
【发布时间】:2017-04-25 11:48:25
【问题描述】:

我无法将用户控件上的自定义依赖属性绑定到我的 MVVM ViewModel。当我直接在视图上使用它时,我的用户控件正常工作:

    <local:CustomControl Mode="{Binding Mode, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Grid.Row="0">
        <Button x:Name="InfoBox1" Content="Test1" />
        <Button x:Name="InfoBox2" Content="Test2" />
    </local:CustomControl>

但是使用它作为itemspaneltemplate绑定不起作用:

    <ItemsControl Grid.Row="0" ItemsSource="{Binding Equipment}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <local:CustomControl Mode="{Binding Mode, Mode=TwoWay}"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

我尝试使用 RelativeSource 并找到 itemscontrol/view 并将路径设置为 Mode 或 DataContext.Mode 但我无法让绑定工作。

模式定义为:

    public static readonly DependencyProperty ModeProperty;

    public Modes Mode
    {
        get { return (Modes)this.GetValue(ModeProperty); }
        set { this.SetValue(ModeProperty, value); }
    }

并在自定义控件的构造函数中注册:

    public CustomControl()
    {
        Mode = Modes.Default;
    }

    static CustomControl()
    {
        ModeProperty = DependencyProperty.Register("Mode", typeof(Modes), typeof(CustomControl), new FrameworkPropertyMetadata(Mode.Default, OnModeChanged));
    }

    private static void OnModeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        CustomControl ctrl= o as CustomControl ;
        if (ctrl== null) return;

        Modes mode = (Modes)e.NewValue;
        ctrl.Mode = mode;
    }

我是否需要使用解决方法来让控件作为面板模板工作,还是我只是把绑定搞砸了?

----编辑

视图模型部分:

    private Modes _mode= Modes.Default;
    public Modes Mode
    {
        get { return _mode; }
        set { _mode= value; NotifyPropertyChanged(); }
    }

    private ObservableCollection<EquipmentViewModel> _equipment;
    public ObservableCollection<EquipmentViewModel> Equipment
    {
        get { return _equipment; }
        set { _equipment = value; NotifyPropertyChanged(); }
    }

----编辑2: 我已经进一步调查并且我更加复杂。我已将以下内容添加到 ItemsPanelTemplate 的控件和直接在网格中的控件中。

 Visibility="{Binding Visible, Converter={StaticResource visibilityConverter}}"

更改此 Visible 布尔值在这两种情况下都有效。所以这似乎只是自定义 DependencyProperty 的问题。

检查可视化树控件的DataContext作为ItemsPanelTemplate也是正确的。

什么可以使依赖属性在直接使用而不是作为项目面板模板时正常工作?

【问题讨论】:

  • ItemsControl 的 DataContext 是什么,Mode 源属性在哪里定义?如果它被定义在与 Equipment 属性相同的类中,它应该可以工作。
  • 模式与我的设备一起在我的视图模型上定义。我有一个按钮来更改它,它适用于第一个 xaml(直接使用自定义控件)。但在 ItemsControl 中,绑定不起作用。
  • 你应该阅读这个:stackoverflow.com/help/mcve
  • 请注意,您的 OnModeChanged 回调完全是多余的。它只是将 Mode 属性设置为它已有的值。请注意,在 属性值发生更改后调用依赖属性更改回调。
  • @Clemens 谢谢

标签: c# wpf binding itemscontrol itemspaneltemplate


【解决方案1】:

找到导致奇怪冲突行为的原因。 我在普通ctor中将属性设置为某个值

public CustomControl()
{
    Mode = Modes.Default;
}

当将控件用作 Itemspanel 模板时,这显然会导致冲突。删除它使绑定按预期工作。

我猜行为的差异与在不同时间对构造函数的调用有关?

【讨论】:

    猜你喜欢
    • 2011-10-13
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 2015-10-08
    相关资源
    最近更新 更多