代码之家  ›  专栏  ›  技术社区  ›  J4N

如何正确绑定子UserControl依赖属性的共享属性

  •  0
  • J4N  · 技术社区  · 7 年前

    我有4个不同的收藏。目前我显示了这4个集合,但一次只能选择一个元素。

    显示4个集合的视图:

    <usercontrol x:class=“xxx.yyy.vvv.menu”
    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:local=“clr命名空间:xxx.yyy.vvv.menu”
    mc:ignorable=“d”
    d:designheight=“800”d:designwidth=“450”>
    <grid name=“rootcontainer”>
    <grid.dataContext>
    <local:菜单视图模型/>
    </grid.dataContext>
    <itemsControl itemssource=“绑定集合”>
    <itemsControl.itemTemplate>
    <数据模板>
    <local:collectioncontrol collection=“binding”selectedElement=“binding path=dataContext.globalSelectedElement,elementName=rootContainer,mode=twoway,updateSourceTrigger=propertyChanged”/>gt;
    </datatemplate>
    </itemscontrol.itemstemplate>
    <itemscontrol.itemspanel>
    <项模板lt;itemspaneltemplate>
    <stackpanel orientation=“垂直”/>
    </itemspaneltemplate>
    </itemscontrol.itemspanel>
    </itemscontrol>
    </grid>
    </usercontrol>
    

    这已绑定到ViewModel:。

    public class menuview model:somebaseview model that handlethenotify
    {
    公共imyelement globalselectedelement
    {
    get=>获取值<imyelement>();
    set=>set value(value);//我从没来过这里!!!)
    }
    公共SomeCollectionContainer集合
    {
    get=>获取值<someCollectionContainer>();
    set=>设置值(value);
    }
    }
    

    我的子控件具有依赖项属性,当UserControl的内部ViewModel更改时,该属性会更改。

    public imyelement selectedElement
    {
    get返回(imyelement)getvalue(selectedelementproperty);
    set set value(selectedelementproperty,value);/*我来了!*/}
    }
    公共静态只读DependencyProperty SelectedElementProperty=
    dependencyProperty.register(“selectedElement”,typeof(imyelement),typeof(collectioncontrol),new propertymetadata(null,onselectedElementChanged));
    
    私有静态void OnSelectedElementChanged(DependencyObject DependencyObject,DependencyPropertyChangedEventArgs DependencyPropertyChangedEventArgs)
    {
    //检索子控件viewModel并设置属性
    SubControlView模型SubControlView模型=(SubControlView模型)((CollectionControl)DependencyObject).rootContainer.dataContext;
    SubControlViewModel.SelectedElement=(imYelement)DependencyPropertiesChangedEventArgs.NewValue;
    }
    
    //在构造函数中,我注册到ViewModel的PropertyChanged,并在其更改时设置SelectedElement。
    

    因此,基本上,我加入了UserControl的Dependency属性的setValue,但我从来没有加入过我的主ViewModel的globalSelectedElementproperty。

    我错过了什么?

    编辑 我试图在我的ViewModel和Dependency属性之间直接使用双向绑定,但也不起作用:

    在我的子控件中:

    <usercontrol x:class=“xxx.yyy.vvv.collectioncontrol”
    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:local=“clr命名空间:xxx.yyy.vvv.menu”
    mc:ignorable=“d”
    d:designheight=“450”d:designwidth=“800”>
    <stackpanel name=“rootcontainer”orientation=“垂直”>
    <stackpanel.dataContext>
    <local:集合控件视图模型/>
    </stackpanel.datacontext>
    <label content=“绑定集合.名称”margin=“5,0,0,0”/>gt;
    <listbox itemssource=“binding collection.items”HorizontalContentAlignment=“Stretch”padding=“0”borderThickness=“0”selectedItem=“binding selectedElement,relativesource=relativesource ancestorType=x:type local:collectionControl,mode=twoway”>
    <listbox.itemtemplate>
    <数据模板>
    ……
    </datatemplate>
    </listbox.itemtemplate>
    <listbox.itemspanel>
    <项模板lt;itemspaneltemplate>
    <stackpanel orientation=“垂直”/>
    </itemspaneltemplate>
    </listbox.itemspanel>
    </listbox>
    </stackpanel>
    </usercontrol>
    

    我觉得我的用户控件依赖属性是从两个方面绑定的

    我试着做一个小图表来展示我的课程。 因此,mycollectioncontrol.selectedElementare correctly set,but themenuView model.selectedItem.are not.

    =

    <UserControl x:Class="xxx.yyy.vvv.Menu"
                 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:local="clr-namespace:xxx.yyy.vvv.Menu"
                 mc:Ignorable="d" 
                 d:DesignHeight="800" d:DesignWidth="450">
        <Grid  Name="RootContainer">
            <Grid.DataContext>
                <local:MenuViewModel/>
            </Grid.DataContext>
            <ItemsControl ItemsSource="{Binding Collection}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <local:CollectionControl Collection="{Binding}" SelectedElement="{Binding Path=DataContext.GlobalSelectedElement,ElementName=RootContainer, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </Grid>
    </UserControl>
    

    它绑定到一个视图模型:

    public class MenuViewModel : SomeBaseViewModelThatHandleTheNotify
    {
        public IMyElement GlobalSelectedElement
        {
            get => GetValue<IMyElement>();
            set => SetValue(value); //I NEVER COME HERE!!!)
        }
        public SomeCollectionContainer Collection
        {
            get => GetValue<SomeCollectionContainer>();
            set => SetValue(value);
        }
    }
    

    我的子控件具有依赖项属性,当UserControl的内部ViewModel更改时,该属性会更改。

        public IMyElement SelectedElement
        {
            get { return (IMyElement)GetValue(SelectedElementProperty); }
            set { SetValue(SelectedElementProperty, value);/*HERE I COME!*/ }
        }
        public static readonly DependencyProperty SelectedElementProperty =
            DependencyProperty.Register("SelectedElement", typeof(IMyElement), typeof(CollectionControl), new PropertyMetadata(null, OnSelectedElementChanged));
    
        private static void OnSelectedElementChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            //Retrieve the sub control ViewModel and set the property
            SubControlViewModel subControlViewModel = (SubControlViewModel)((CollectionControl)dependencyObject).RootContainer.DataContext;
            subControlViewModel.SelectedElement = (IMyElement)dependencyPropertyChangedEventArgs.NewValue;
        }
    
        //In the constructor, I register to PropertyChanged of the ViewModel, and I set the SelectedElement when it change.
    

    所以,基本上,我输入了UserControl的Dependency属性的setValue,但我从未输入GlobalSelectedElement我的主视图模型的属性。

    我错过了什么?

    编辑 我试图直接在我的ViewModel和Dependency属性之间使用双向绑定,但也不起作用:

    在我的子控件中:

    <UserControl x:Class="xxx.yyy.vvv.CollectionControl"
                 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:local="clr-namespace:xxx.yyy.vvv.Menu"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <StackPanel Name="RootContainer" Orientation="Vertical">
            <StackPanel.DataContext>
                <local:CollectionControlViewModel/>
            </StackPanel.DataContext>
            <Label Content="{Binding Collection.Name}" Margin="5,0,0,0" />
            <ListBox ItemsSource="{Binding Collection.Items}" HorizontalContentAlignment="Stretch" Padding="0" BorderThickness="0" SelectedItem="{Binding SelectedElement, RelativeSource={RelativeSource AncestorType={x:Type local:CollectionControl}}, Mode=TwoWay}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        ...
                    </DataTemplate>
                </ListBox.ItemTemplate>
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
        </StackPanel>
    </UserControl>
    

    我觉得我的用户控件依赖属性是从两个方面绑定的

    我试着做一个小图表来展示我的课程。 所以我的CollectionControl.SelectedElement设置正确,但MenuViewModel.SelectedItem不是。

    1 回复  |  直到 7 年前
        1
  •  0
  •   mm8    7 年前

    DataContext ItemsControl RelativeSource

    <local:CollectionControl Collection="{Binding}" 
                             SelectedElement="{Binding Path=DataContext.GlobalSelectedElement, RelativeSource={RelativeSource AncestorType=ItemsControl}, Mode=TwoWay}"/>
    

    ElementName namescopes CollectionControl ItemTemplate

    推荐文章