Connot bind to Command

Apr 18, 2011 at 1:59 PM

View XAML:

<UserControl x:Class="MES.Modules.Main.Navigation.NavigationListView"
                    xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
                    Name="this"
             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:extToolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
            
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <CollectionViewSource Source="{Binding}" x:Key="cvs1"/>
        <Style x:Key="LinkButton" TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <ControlTemplate.Resources>
                            <Style TargetType="{x:Type TextBlock}">
                                <Setter Property="TextDecorations" Value="Underline" />
                            </Style>
                        </ControlTemplate.Resources>
                        <ContentPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="Cursor" Value="Hand" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
        
             
        <HierarchicalDataTemplate x:Key="NavigationTemplate" 
                                  ItemsSource="{Binding Path=SubNavItemList}">
            <Grid>
                <Button Content="{Binding Name}" 
                        Style="{StaticResource LinkButton}">
                    <Button.InputBindings >
                        <MouseBinding Gesture="LeftDoubleClick" 
                                          Command="{Binding Path=NavItemDoubleClickCommand,Source={StaticResource cvs1}}"
                                          CommandParameter="{Binding}"/>
                    </Button.InputBindings>

                </Button>
                
            </Grid>
        </HierarchicalDataTemplate>
    </UserControl.Resources>
    
    <Grid x:Name="LayoutRoot">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition />
            </Grid.RowDefinitions>
            
                <TreeView  x:Name="NavigatinTreeView"
                  ItemsSource="{Binding Model}"
                  ItemTemplate="{StaticResource NavigationTemplate}" 
                  Style="{StaticResource NavigationTreeViewStyle}"                 
                  >
                  

        </TreeView>
        
        <extToolkit:BusyIndicator IsBusy="{Binding Path=IsBusy}"  BusyContent="Downloading email..." >

        </extToolkit:BusyIndicator>
            <Button Name ="Button1" Grid.Row=" 1" Content="Test" Click="Button_Click">
                
            </Button>

        </Grid>

    </Grid>
</UserControl>

Behind Code:
using System.ComponentModel.Composition;
using System.Windows.Controls;
using System.Diagnostics.CodeAnalysis;
using MES.Infrastructure;
using AvalonDock;
using System.Windows.Data;

namespace MES.Modules.Main.Navigation
{
    [ViewExport(RegionName = RegionNames.MainRegion, ViewName = "NavigationListView")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public partial class NavigationListView : UserControl 
    {
        public NavigationListView()
        {
            InitializeComponent();
        }

        [Import]
        [SuppressMessage("Microsoft.Design", "CA1044:PropertiesShouldNotBeWriteOnly", Justification = "Needs to be a property to be composed by MEF")]
        public NavItemListViewModel ViewModel
        {
            set
            {
                this.DataContext = value;
            }
        }

        private void Button1_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Button cmd = (Button)sender;

            CollectionViewSource src = (CollectionViewSource)cmd.FindResource("cvs1");
           
        }
    }
}

ViewModel:
using System;
using Csla.Xaml;
using Csla;
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.Events;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.ServiceLocation;
using MES.Modules.Main.Models;
using MES.Infrastructure;
namespace MES.Modules.Main.Navigation
{
    [Export(typeof(NavItemListViewModel))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class NavItemListViewModel:ViewModel<NavItemList>
    {
         #region Private members

        private readonly IRegionManager regionManager;
        private readonly IEventAggregator eventAggregator;

        #endregion

        #region Commandes

     
        public ICommand NavItemDoubleClickCommand { get; private set; }
             

        #endregion


        #region Constructor
        [ImportingConstructor]
        public NavItemListViewModel(IRegionManager regionManager, IEventAggregator eventAggregator)
        {

            this.InitializeCommands();

            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;

            InitData();

        }

        #endregion

        #region InitializeCommands Method
               
        public void InitializeCommands()
        {
            NavItemDoubleClickCommand = new DelegateCommand<object>(NavItemDoubleClick);
        }

        #endregion

        void InitData()
        {
            BeginRefresh("GetAll");
        }


        private void NavItemDoubleClick(object navItem)
        {
            /* if (menuItem is ProductCategory)
             {
                 var productCategory = menuItem as ProductCategory;
                 if (productCategory.ProductCategoryID > 0) // Category selected
                     eventAggregator.Publish(new CategorySelectedEvent(productCategory));
                 else // Category "all products" selected
                     eventAggregator.Publish(new CategorySelectedEvent());
             }
             else if (menuItem is ProductSubcategory)
             {
                 eventAggregator.Publish(new CategorySelectedEvent((ProductSubcategory)menuItem));
             }*/
            NavItem item = navItem as NavItem;
           // if (!string.IsNullOrEmpty(item.Name))
               // ShowView(item.ViewName);
        }


    }
}

When click the button1, the viewcollectonsource is null, is there any error?


Apr 18, 2011 at 3:22 PM

 

SubNavItemList this property is never defined anywhere.  So there is nothing for the button to do with the command you have defined. Secondly what are you wanting to put into the CollectionViewSource?
The result you are seeing is probably correct.  Are you trying to populate the CollectionViewSource with the NavItemList?  I am assuming that your trying to test the collection with the Button_Click event?
Your Output window in VS2010 should be filled with Binding Expression Errors, I imagine.
Apr 18, 2011 at 5:17 PM
Edited Apr 18, 2011 at 5:19 PM

..

Apr 18, 2011 at 5:18 PM
Edited Apr 18, 2011 at 5:19 PM

Model:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
using Csla.Serialization;


namespace MES.Modules.Main.Models
{
    [Serializable ]
   public class NavItemList:ReadOnlyListBase <NavItemList ,NavItem >
    {
        #region Authorization Rules

        private static void AddObjectAuthorizationRules()
        {
            // TODO: add authorization rules
            //AuthorizationRules.AllowGet(typeof(ReadOnlyChildList), "Role");
        }

        #endregion

        #region Default Constructor
           private NavItemList() { }
        #endregion

        #region Asynchronous Factory Methods
        public static void New(EventHandler<DataPortalResult<NavItemList>> callback)
        {
            var dp = new DataPortal<NavItemList>();
            dp.CreateCompleted += callback;
            dp.BeginCreate();
        }

        public static void Get(int id, EventHandler<DataPortalResult<NavItemList>> callback)
        {
            var dp = new DataPortal<NavItemList>();
            dp.FetchCompleted += callback;
           // dp.BeginFetch(new NavMenu.Key(id));
        }

        public static void GetAll(EventHandler<DataPortalResult<NavItemList>> callback)
        {
            var dp = new DataPortal<NavItemList>();
            dp.FetchCompleted += callback;
            dp.BeginFetch();
        }
        #endregion // Asynchronous Factory Methods

        #region Data Access

        private void ReadData(IEnumerable<MES.Server.Entities.NavigationItem> data)
        {
                 
            RaiseListChangedEvents = false;
            IsReadOnly = false;

            foreach (var item in data)
                this.Add(NavItem.Get(item));
            IsReadOnly = true;
            RaiseListChangedEvents = true;

        
        }	



        private void DataPortal_Fetch()
        {
            using (var ctx = Csla.Data.ObjectContextManager<MES.Server .Entities.SecurityEntityModelContainer>.GetManager(MES.Server.Entities.Database.Security ))
                ReadData(ctx.ObjectContext.NavigationItem.Where(p => p.ParentId == null));
        }

        private void Child_Fetch(int id)
        {
            using (var ctx = Csla.Data.ObjectContextManager<MES.Server.Entities.SecurityEntityModelContainer>.GetManager(MES.Server.Entities.Database.Security))
                ReadData(ctx.ObjectContext.NavigationItem.Where(p => p.ParentId == id));
        }

        #endregion
    }
}

 

 

 

using System;
using Csla;
using Csla.Data;

namespace MES.Modules.Main.Models
{
    [Serializable]
    public class NavItem : ReadOnlyBase<NavItem>
    {
        #region Business Methods

        public static readonly PropertyInfo<int> IdProperty = RegisterProperty<int>(c => c.Id);
        public int Id
        {
            get { return GetProperty(IdProperty); }
            private set { LoadProperty(IdProperty, value); }
        }

        public static readonly PropertyInfo<string> NameProperty = RegisterProperty<string>(c => c.Name);
        public string Name
        {
            get { return GetProperty(NameProperty); }
            private set { LoadProperty(NameProperty, value); }
        }
        public static readonly PropertyInfo<NavItemList> SubNavItemListProperty = RegisterProperty<NavItemList>(c => c.SubNavItemList, RelationshipTypes.Child | RelationshipTypes.LazyLoad);
        public NavItemList SubNavItemList
        {
            get
            {
                if (!FieldManager.FieldExists(SubNavItemListProperty))
                {
                    DataPortal.BeginFetch<NavItemListCreator>(Id,(o,e) =>
                      {
                          if (e.Error != null)
                              throw e.Error;
                          else 
                              SubNavItemList =e.Object.Result;

                      });
                    return null;
                }
                return GetProperty(SubNavItemListProperty);
            }
            private set
            {
                LoadProperty(SubNavItemListProperty, value);
                OnPropertyChanged(SubNavItemListProperty);
            }
        }
       
        #endregion


        #region Default Constructor

        private NavItem() { }

        #endregion

        #region Synchronous Factory Methods

        internal static NavItem Get(MES.Server .Entities .NavigationItem data)
        {
            if (data == null)
                return null;

            return DataPortal.FetchChild<NavItem>(data);
        }
        #endregion 


        private void Child_Fetch(MES.Server .Entities .NavigationItem  data)
        {
            LoadProperty(IdProperty, data.Id);
           // LoadProperty(ParentIdProperty, data.ParentId);
            LoadProperty(NameProperty, data.Name);
           // LoadProperty(TypeProperty, data.Type);
          //  LoadProperty(ViewNameProperty, data.ViewName);
          //  LoadProperty(BindingResourceKeyProperty, data.BindingResourceKey);
          //  LoadProperty(ModelProperty, data.Model);
        }

    }
}

If I use code as below, it can triger the viewmodel.command
<UserControl x:Class="MES.Modules.Main.Navigation.NavigationListView"
                    xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
                    Name="this"
             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:extToolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
            
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        
    </UserControl.Resources>
    
    <Grid x:Name="LayoutRoot">
        <Grid>
            <Button Name="Button1" Content="Test"   
                Command="{Binding Path=NavItemDoubleClickCommand}"          

                CommandParameter="{Binding}" >

            </Button>



            <extToolkit:BusyIndicator IsBusy="{Binding Path=IsBusy}"  BusyContent="Downloading email..." >

            </extToolkit:BusyIndicator>
         
         
        </Grid>

    </Grid>
</UserControl>

but I use code as below, it cannot triger the command in viewmodel
<Grid>
            <Button Name="Button1" Content="Test"   
                Command="{Binding Path=NavItemDoubleClickCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl }}"          

                CommandParameter="{Binding}" >

            </Button>

            <extToolkit:BusyIndicator IsBusy="{Binding Path=IsBusy}"  BusyContent="Downloading email..." >

            </extToolkit:BusyIndicator>
         
         
        </Grid>

what's the error?

Apr 19, 2011 at 5:49 PM

public NavItemList SubNavItemList
        {
            get
            {
                if (!FieldManager.FieldExists(SubNavItemListProperty))
                {
                    DataPortal.BeginFetch<NavItemListCreator>(Id,(o,e) =>
                      {
                          if (e.Error != null)
                              throw e.Error;
                          else 
                              SubNavItemList =e.Object.Result;

                      });
                    return null;
                }
                return GetProperty(SubNavItemListProperty);
            }

Not that i have had a chance to play with CSLA much but that item I bolded and underlined and italicized wouldn't that be part of the problem?  If you return from this property every time it will be null... 
Assuming it is inside the logic.