我怎样才能绑定自定义属性从视图视图模型上code后面? [英] How can I bind custom properties from View to ViewModel on code behind?

查看:207
本文介绍了我怎样才能绑定自定义属性从视图视图模型上code后面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一个页面的MainPage 和用户控件寻呼机。两者都有自己的视图模型。在寻呼机,有三个依赖属性来源。我想从寻呼机的观寻呼机的视图模型通过这些属性。我想这对查看的code后面。但它不工作...的设置 PagerViewModel 物业从来没有在调试调用。请帮我...

下面是详细的机制:

MainPageViewModel

↓与绑定值传递

的MainPage

↓与设定值THT性质从 MainPagerViewModel

寻呼机(code后面)

↓绑定属性PagerViewModel< ---这部分是问题!

PagerViewModel

↓与绑定值传递

寻呼机(XAML)

和这里是源

[MainPageViewModel.cs]

  System.Collections中使用;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Linq的;
使用System.Windows;
使用System.Windows.Controls的;
使用System.Windows.Data;
使用System.Windows.Media;
使用Client.Model;命名空间Client.ViewModel
{
    公共类MainPageViewModel:ViewModelBase
    {
        ...
        公众的ObservableCollection< IPagableEntry> PagerTableCategoriesItems {{返回TableCategoryRepository.Instance.TableCategories; }}        公众诠释PagerTableCategoriesRows {{返回1; }}        公众诠释PagerTableCategoriesColumns {{返回3; }}
        ...
    }
}

[MainPage.xaml中]

 <页的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
      的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
      的xmlns:鉴于=CLR的命名空间:Client.View
      的xmlns:视图模型=CLR的命名空间:Client.ViewModel
      的xmlns:resStr =CLR的命名空间:Client.CommonResources.String
      X:类=Client.View.MainPage
      风格={StaticResource的共同}>
    < Page.DataContext>
        <视图模型:MainPageViewModel />
    < /Page.DataContext>
    ...    <查看:传呼机X:NAME =pagerTableCategories
                来源={绑定路径= PagerTableCategoriesItems}
                行={绑定路径= PagerTableCategoriesRows}
                列={绑定路径= PagerTableCategoriesColumns}>
    < /视图:寻呼机GT;
    ...
< /页>

[Pager.xaml.cs]

 使用系统;
System.Collections中使用;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.ComponentModel;
使用System.Linq的;
使用System.Runtime.CompilerServices;
使用System.Text;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls的;
使用System.Windows.Controls.Primitives;
使用System.Windows.Data;
使用System.Windows.Input;
使用Client.Model;
使用Client.ViewModel;命名空间Client.View
{
    公共部分类寻呼机
    {        公共静态只读的DependencyProperty在SourceProperty = DependencyProperty.Register(源,typeof运算(的ObservableCollection< IPagableEntry>)的typeof(寻呼机),新PropertyMetadata(NULL,OnSourceChanged));
        公共静态只读的DependencyProperty RowsProperty = DependencyProperty.Register(行的typeof(INT)的typeof(寻呼机),新PropertyMetadata(1,OnRowsChanged));
        公共静态只读的DependencyProperty ColumnsProperty = DependencyProperty.Register(列的typeof(INT)的typeof(寻呼机),新PropertyMetadata(1,OnColumnsChanged));
        公共静态只读的DependencyProperty SelectedEntryProperty = DependencyProperty.Register(SelectedEntry的typeof(对象)的typeof(寻呼机),新PropertyMetadata(NULL,OnSelectedEntryChanged));        公众诠释行
        {
            {返回(INT)的GetValue(RowsProperty); }
            集合{的SetValue(RowsProperty,值); }
        }        公众诠释列
        {
            {返回(INT)的GetValue(ColumnsProperty); }
            集合{的SetValue(ColumnsProperty,值); }
        }        公共对象SelectedEntry
        {
            {返回的GetValue(SelectedEntryProperty); }
            集合{的SetValue(SelectedEntryProperty,值); }        }        公众的ObservableCollection< IPagableEntry>资源
        {
            {返回(的ObservableCollection< IPagableEntry>)的GetValue(在SourceProperty); }
            集合{的SetValue(在SourceProperty,值); }
        }        公共寻呼机()
        {
            的InitializeComponent();            //我要绑定的三个自定义属性(行,列,资料)以PagerViewModel的行,列,集合
            结合bindingRows =新的绑定(行);
            bindingRows.Mode = BindingMode.TwoWay;
            bindingRows.Source = gridPager.DataContext;
            gridPager.SetBinding(RowsProperty,bindingRows);            结合bindingColumns =新的绑定(列);
            bindingColumns.Mode = BindingMode.TwoWay;
            bindingColumns.Source = gridPager.DataContext;
            gridPager.SetBinding(ColumnsProperty,bindingColumns);            绑定的BindingSource =新的绑定(集合);
            bindingSource.Mode = BindingMode.TwoWay;
            bindingSource.Source = gridPager.DataContext;
            gridPager.SetBinding(在SourceProperty,BindingSource的);
        }        私人无效ListBoxEntriesOnSelectionChanged(对象发件人,SelectionChangedEventArgs E)
        {
            SelectedEntry =(发件人为列表框).SelectedItem;
        }        私有静态无效OnSelectedEntryChanged(DependencyObject的寻呼机,DependencyPropertyChangedEventArgs E)
        {
            (寻呼机寻呼机).SelectedEntry = e.NewValue;
        }        私有静态无效OnSourceChanged(DependencyObject的寻呼机,DependencyPropertyChangedEventArgs E)
        {
            (寻呼机寻呼机).Source =(的ObservableCollection< IPagableEntry>)e.NewValue;
        }        私有静态无效OnRowsChanged(DependencyObject的寻呼机,DependencyPropertyChangedEventArgs E)
        {
            (寻呼机寻呼机).Rows =(INT)e.NewValue;
        }        私有静态无效OnColumnsChanged(DependencyObject的寻呼机,DependencyPropertyChangedEventArgs E)
        {
            (寻呼机寻呼机).Columns =(INT)e.NewValue;
        }    }
}

[Pager.xaml]

 <用户控件的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
             的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
             的xmlns:鉴于=CLR的命名空间:Client.View
             的xmlns:视图模型=CLR的命名空间:Client.ViewModel
             的xmlns:resStr =CLR的命名空间:Client.CommonResources.String
             X:类=Client.View.Pager>
    <电网X:NAME =gridPager>
        < Grid.DataContext>
            <视图模型:PagerViewModel />
        < /Grid.DataContext>        ...        < ListBox的X:名称=listBoxEntries
                 的ItemsSource ={绑定路径=集合}
                 了borderThickness =0
                 余量=0
                 风格={StaticResource的共同}
                 Horizo​​ntalContentAlignment =弹力
                 VerticalContentAlignment =弹力
                 的ItemTemplate ={StaticResource的templateTableCategory}
                 的SelectedItem ={绑定路径= SelectedEntry,模式=双向}
                 的SelectionChanged =ListBoxEntriesOnSelectionChanged>
            < ListBox.ItemsPanel>
                < ItemsPanelTemplate>
                    < UniformGrid行={绑定路径=行}
                                 列={绑定路径=列}
                                 IsItemsHost =真/>
                < / ItemsPanelTemplate>
            < /ListBox.ItemsPanel>
        < /列表框>        ...    < /网格和GT;
< /用户控件>

[PagerViewModel.cs]

  System.Collections中使用;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Linq的;
使用System.Windows.Data;
使用System.Windows.Media;
使用Client.Model;命名空间Client.ViewModel
{
    公共类PagerViewModel:ViewModelBase
    {        ...        的ListCollectionView _listCollectionView;
        的ObservableCollection< IPagableEntry> _采集;
        诠释_rows;
        INT _columns;        公众诠释行
        {
            {返回_rows; }
            组
            {
                _rows =价值;
                OnPropertyChanged();
            }
        }        公众诠释列
        {
            {返回_columns; }
            组
            {
                _columns =价值;
                OnPropertyChanged();
            }
        }        公众的ListCollectionView的ListCollectionView
        {
            {返回_listCollectionView; }
            组
            {
                _listCollectionView =价值;
                OnPropertyChanged();
            }
        }        公众的ObservableCollection< IPagableEntry>采集
        {
            得到
            {
                返回_collection;
            }            组
            {
                _collection =价值;
                OnPropertyChanged();
            }
        }        ...    }
}


解决方案

据我能理解这个问题是二的ViewModels之间创建一个同步机制。我和彼得的理论完全agry,但我建议你在下次同步解决方案。为了解决这个问题,我想建议你使用一个模型水平同步化。只要把你所需的详细信息到一个光模型类,并注入这个小模型成所需的ViewModels。下面是该方案:

问候,

I made a Page MainPage and a UserControl Pager. Both have their ViewModel. In Pager, there are three dependency properties Rows, Columns, Source. I want to pass these properties from Pager's View to Pager's ViewModel. I tried this on View's code behind. But it doesn't work...the set property in PagerViewModel never be called on debugging. Please, help me...

Here is detail mechanism:

MainPageViewModel

↓Pass the values with binding

MainPage

↓Set tht properties with values from MainPagerViewModel

Pager(code behind)

↓Bind the properties to PagerViewModel <--- This part is PROBLEM!!!

PagerViewModel

↓Pass the values with binding

Pager(XAML)

and here is source

[MainPageViewModel.cs]

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Client.Model;

namespace Client.ViewModel
{
    public class MainPageViewModel : ViewModelBase
    {
        ...
        public ObservableCollection<IPagableEntry> PagerTableCategoriesItems { get { return TableCategoryRepository.Instance.TableCategories; } }

        public int PagerTableCategoriesRows { get { return 1; } }

        public int PagerTableCategoriesColumns { get { return 3; } }
        ...
    }
}

[MainPage.xaml]

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:view="clr-namespace:Client.View"
      xmlns:viewModel="clr-namespace:Client.ViewModel"
      xmlns:resStr="clr-namespace:Client.CommonResources.String"
      x:Class="Client.View.MainPage"
      Style="{StaticResource common}">
    <Page.DataContext>
        <viewModel:MainPageViewModel />
    </Page.DataContext>
    ...

    <view:Pager x:Name="pagerTableCategories"
                Source="{Binding Path=PagerTableCategoriesItems}"
                Rows="{Binding Path=PagerTableCategoriesRows}"
                Columns="{Binding Path=PagerTableCategoriesColumns}">
    </view:Pager>
    ...
</Page>

[Pager.xaml.cs]

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using Client.Model;
using Client.ViewModel;

namespace Client.View
{
    public partial class Pager
    {

        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(ObservableCollection<IPagableEntry>), typeof(Pager), new PropertyMetadata(null, OnSourceChanged));
        public static readonly DependencyProperty RowsProperty = DependencyProperty.Register("Rows", typeof(int), typeof(Pager), new PropertyMetadata(1, OnRowsChanged));
        public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(Pager), new PropertyMetadata(1, OnColumnsChanged));
        public static readonly DependencyProperty SelectedEntryProperty = DependencyProperty.Register("SelectedEntry", typeof(object), typeof(Pager), new PropertyMetadata(null, OnSelectedEntryChanged));

        public int Rows
        {
            get { return (int)GetValue(RowsProperty); }
            set { SetValue(RowsProperty, value); }
        }

        public int Columns
        {
            get { return (int)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }

        public object SelectedEntry
        {
            get { return GetValue(SelectedEntryProperty); }
            set { SetValue(SelectedEntryProperty, value); }

        }

        public ObservableCollection<IPagableEntry> Source
        {
            get { return (ObservableCollection<IPagableEntry>)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        public Pager()
        {
            InitializeComponent();

            // I want to bind the three custom properties(Rows, Columns, Source) to PagerViewModel's Rows, Columns, Collection
            Binding bindingRows = new Binding("Rows");
            bindingRows.Mode = BindingMode.TwoWay;
            bindingRows.Source = gridPager.DataContext;
            gridPager.SetBinding(RowsProperty, bindingRows);

            Binding bindingColumns = new Binding("Columns");
            bindingColumns.Mode = BindingMode.TwoWay;
            bindingColumns.Source = gridPager.DataContext;
            gridPager.SetBinding(ColumnsProperty, bindingColumns);

            Binding bindingSource = new Binding("Collection");
            bindingSource.Mode = BindingMode.TwoWay;
            bindingSource.Source = gridPager.DataContext;
            gridPager.SetBinding(SourceProperty, bindingSource);
        }

        private void ListBoxEntriesOnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            SelectedEntry = (sender as ListBox).SelectedItem;
        }

        private static void OnSelectedEntryChanged(DependencyObject pager, DependencyPropertyChangedEventArgs e)
        {
            (pager as Pager).SelectedEntry = e.NewValue;
        }

        private static void OnSourceChanged(DependencyObject pager, DependencyPropertyChangedEventArgs e)
        {
            (pager as Pager).Source = (ObservableCollection<IPagableEntry>)e.NewValue;
        }

        private static void OnRowsChanged(DependencyObject pager, DependencyPropertyChangedEventArgs e)
        {
            (pager as Pager).Rows = (int)e.NewValue;
        }

        private static void OnColumnsChanged(DependencyObject pager, DependencyPropertyChangedEventArgs e)
        {
            (pager as Pager).Columns = (int)e.NewValue;
        }

    }
}

[Pager.xaml]

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:view="clr-namespace:Client.View"
             xmlns:viewModel="clr-namespace:Client.ViewModel"
             xmlns:resStr="clr-namespace:Client.CommonResources.String"
             x:Class="Client.View.Pager">
    <Grid x:Name="gridPager">
        <Grid.DataContext>
            <viewModel:PagerViewModel />
        </Grid.DataContext>

        ...

        <ListBox x:Name="listBoxEntries"
                 ItemsSource="{Binding Path=Collection}"
                 BorderThickness="0"
                 Margin="0"
                 Style="{StaticResource common}"
                 HorizontalContentAlignment="Stretch"
                 VerticalContentAlignment="Stretch"
                 ItemTemplate="{StaticResource templateTableCategory}"
                 SelectedItem="{Binding Path=SelectedEntry, Mode=TwoWay}"
                 SelectionChanged="ListBoxEntriesOnSelectionChanged">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="{Binding Path=Rows}"
                                 Columns="{Binding Path=Columns}"
                                 IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>

        ...

    </Grid>
</UserControl>

[PagerViewModel.cs]

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Data;
using System.Windows.Media;
using Client.Model;

namespace Client.ViewModel
{
    public class PagerViewModel : ViewModelBase
    {

        ...

        ListCollectionView _listCollectionView;
        ObservableCollection<IPagableEntry> _collection;
        int _rows;
        int _columns;

        public int Rows
        {
            get { return _rows; }
            set
            {
                _rows = value;
                OnPropertyChanged();
            }
        }

        public int Columns
        {
            get { return _columns; }
            set
            {
                _columns = value;
                OnPropertyChanged();
            }
        }

        public ListCollectionView ListCollectionView
        {
            get { return _listCollectionView; }
            set
            {
                _listCollectionView = value;
                OnPropertyChanged();
            }
        }

        public ObservableCollection<IPagableEntry> Collection
        {
            get
            {
                return _collection;
            }

            set
            {
                _collection = value;
                OnPropertyChanged();
            }
        }

        ...

    }
}

解决方案

As I can understand the problem is the creating a synchronization mechanism between two viewmodels. I'm completely agry with Peter's theory, but I suggest you the next synchronization solution. To solve this problem I'd like to advice you to use a model level syncronization. Just put your required details into a light model class and inject this small model into desired viewmodels. Here is the scheme:

regards,

这篇关于我怎样才能绑定自定义属性从视图视图模型上code后面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆