自定义控件绑定问题(Windows通用10)

时间:2016-03-23 15:01:18

标签: c# wpf mvvm binding win-universal-app

我试图将自定义控件的参数绑定到列表中。但是它会在错误的ViewModel中搜索。它在我的控件的ViewModel(ViewModelUserControlVM)中搜索,而不是我的控件所在页面的ViewModel。

用户控制xaml

 <UserControl.DataContext>
    <vm:ViewModelUserControlVM/>
</UserControl.DataContext>

<ListView Name="lst">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

背后的用户控制代码

    public object ItemsSource
    {
        get
        {
            return (object)GetValue(ItemsSourceProperty);
        }
        set
        {
            SetValue(ItemsSourceProperty, value);
        }
    }

    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register
        (
        "ItemsSource",
        typeof(object),
        typeof(FlipListview),
        new PropertyMetadata(
            new object(),
            new PropertyChangedCallback(OnItemsSourceChanged)
        )
    );

主页xaml

    <local:CustomControl ItemsSource="{Binding list, Mode=TwoWay}">

修改

MainPage.xaml中

<Page.DataContext>
    <vm:MainPageVM/>
</Page.DataContext>

MainPageVM

    public class MainPageVM : ViewModelBase
    {
    public List<Model> list { get; set; }
    public RelayCommand SelectedItemCommand { get; set; }

    public Model SelectedItem { get; set; }

    public MainPageVM()
    {
        SelectedItem = new Model();
        SelectedItemCommand = new RelayCommand(SelectedItem);

        list = new List<Model>();

        for (int i = 0; i < 5; i++)
        {
            list.Add(new Model("url" + i, "title" + i, "desc" + i));
        }
        RaisePropertyChanged(() => list);
    }
   }

背后的用户控制代码

        public CustomControl()
        {
        this.InitializeComponent();
        }

提前感谢。

2 个答案:

答案 0 :(得分:0)

也许它会像这样工作:

 <local:CustomControl ItemsSource="{x:Bind ViewModel.list, Mode=TwoWay}">

您可以找到有关x:Bind here

的其他信息

答案 1 :(得分:0)

如果UserControl的DataContext是ViewModelUserControlVM,则其中的任何绑定都将查找该DataContext。如果需要父控件绑定到依赖项属性以从其(父控件)DataContext传递某些内容,则可以将UserControls主面板的DataContext(Grid,StackPanel等)设置为ViewModelUserControlVM。这将使控件本身在可视树中看起来“向上”以查找DataContext。在这种情况下,您的MainPage的viewmodel。

您共享的部分代码显示您正在尝试将ItemsSource依赖项属性绑定到MainPage中的某些内容,但是通过将整个UserControl的DataContext分配给不同的viewmodel来覆盖UserControl的DataContext。

更完整的代码将支持或反对这一理论。

更新

感谢您提供额外的代码。目前还不清楚最终目标是什么 - 例如,提到了所选项目但未使用,我们不知道用户控件的viewmodel的相关性。所以,我把一些简单地显示在主视图模型中的列表并绑定到正在查找该类型列表的usercontrol。我希望它能帮助你找到你要去的地方...... (注意:我使用了MVVMLight库)

MainPageVM:

public class MainPageVM : ViewModelBase
    {
        private List<Model> _list = new List<Model>();
        public List<Model> list
        {
            get { return _list; }
            set { Set(ref _list, value); }
        }



        public MainPageVM()
        {
            for (int i = 0; i < 5; i++)
            {
                list.Add(new Model("url" + i, "title" + i, "desc" + i));
            }
            RaisePropertyChanged(() => list);
        }
    }

MainPage xaml(DataContext是MainVM):

<Page
    x:Class="App8.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App8"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.DataContext>
        <local:MainPageVM />
    </Page.DataContext>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <local:CustomControl ItemsSource="{Binding list, Mode=OneWay}" />
    </Grid>
</Page>

后面的CustomControl代码(注意ctor中的datacontext设置 - 控件的DataContext是使用它的任何东西,但LayoutRoot网格中的控件将使用控件的依赖属性):

public CustomControl()
        {
            this.InitializeComponent();
            LayoutRoot.DataContext = this;
        }



        public List<Model> ItemsSource
        {
            get { return (List<Model>)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(List<Model>), typeof(CustomControl), new PropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged)));

        private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }
    }

CustomControl xaml:

<UserControl
    x:Class="App8.CustomControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App8"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <Grid x:Name="LayoutRoot">
        <ListView Name="lst" ItemsSource="{Binding ItemsSource, Mode=OneWay}" 
                  DisplayMemberPath="Url">
        </ListView>
    </Grid>
</UserControl>

简而言之,ListView的itemsource绑定到CustomControl的ItemsSource依赖属性。 CustomControl的ItemsSource的DataContext是使用该控件的DataContext。我希望它可以帮助你。