Как ItemsControl текстовое поле textchange событие вызова? - PullRequest
0 голосов
/ 16 марта 2012

в общем случае TextBox control TextChanged событие работает, но в ItemsControl событие TextBox TextChanged не запускается, как я могу это сделать. Я пытаюсь сделать это с помощью следующего кода, который я реализовал, но не получаю желаемого результата.

Итак, что я делаю не так?

View

<Window x:Class="SoniSoft.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ff="clr-namespace:SoniSoft"
        Title="Window1" Height="300" Width="300">

    <Window.DataContext>
                <ff:ViewModels/>
            </Window.DataContext>
    <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="38"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
    <TextBox Grid.Row="0" ff:TextBoxBehaviour.TextChangedCommand="{Binding TextChanged}"  />

    <ItemsControl Margin="7,0,0,0" Grid.Row="3" ItemsSource="{Binding Path=ViewModelSearchResults}" x:Name="list">
                <ItemsControl.ItemTemplate>
                    <DataTemplate >
                        <Grid>
                            <TextBox  ff:TextBoxBehaviour.TextChangedCommand="{Binding TextChanged}" Text="{Binding Path=CategoryName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="14" FontWeight="Normal" x:Name=" TextBoxCategoryName" />
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>
    </Window>

Просмотр моделей

class ViewModels :ViewModelBase
            {
                public ObservableCollection<Category> AllCategorys = new ObservableCollection<Category>();
                DatabaseDataContext db = new DatabaseDataContext();
                private ListCollectionView _objViewModelSearchResults;
                public ListCollectionView ViewModelSearchResults
                {
                    get { return _objViewModelSearchResults; }
                    set
                    {
                        _objViewModelSearchResults = value;
                        OnPropertyChanged("ViewModelSearchResults");
                    }
                }
                public ViewModels()
                {
                    AllCategorys.Clear();
                    foreach (var item in db.Categories.OrderBy(c => c.CategoryName))
                    {
                        AllCategorys.Add(item);
                    }
                    ViewModelSearchResults = new ListCollectionView(AllCategorys);
                }
                public ICommand TextChanged
                {
                    get
                    {
                        //  this is very lazy: I should cache the command!
                        return new TextChangedCommand();
                    }
                }
        private class TextChangedCommand : ICommand
                {
                    public event EventHandler CanExecuteChanged;
                    public void Execute(object parameter)
                    {
                        MessageBox.Show("Text Changed");
                    }

                    public bool CanExecute(object parameter)
                    {
                        return true;
                    }
                }
            }

DependencyProperty

class EventBehaviourFactory
                {
                    public static DependencyProperty CreateCommandExecutionEventBehaviour(RoutedEvent routedEvent, string propertyName, Type ownerType)
                    {
                        DependencyProperty property = DependencyProperty.RegisterAttached(propertyName, typeof(ICommand), ownerType,
                                                                           new PropertyMetadata(null,
                                                                               new ExecuteCommandOnRoutedEventBehaviour(routedEvent).PropertyChangedHandler));

                        return property;
                    }
    private class ExecuteCommandOnRoutedEventBehaviour : ExecuteCommandBehaviour
                    {
                        private readonly RoutedEvent _routedEvent;

                        public ExecuteCommandOnRoutedEventBehaviour(RoutedEvent routedEvent)
                        {
                            _routedEvent = routedEvent;
                        }

                        /// <summary>
                        /// Handles attaching or Detaching Event handlers when a Command is assigned or unassigned
                        /// </summary>
                        /// <param name="sender"></param>
                        /// <param name="oldValue"></param>
                        /// <param name="newValue"></param>
                        protected override void AdjustEventHandlers(DependencyObject sender, object oldValue, object newValue)
                        {
                            UIElement element = sender as UIElement;
                            if (element == null) { return; }

                            if (oldValue != null)
                            {
                                element.RemoveHandler(_routedEvent, new RoutedEventHandler(EventHandler));
                            }

                            if (newValue != null)
                            {
                                element.AddHandler(_routedEvent, new RoutedEventHandler(EventHandler));
                            }
                        }

                        protected void EventHandler(object sender, RoutedEventArgs e)
                        {
                            HandleEvent(sender, e);
                        }
                    }

                    internal abstract class ExecuteCommandBehaviour
                    {
                        protected DependencyProperty _property;
                        protected abstract void AdjustEventHandlers(DependencyObject sender, object oldValue, object newValue);

                        protected void HandleEvent(object sender, EventArgs e)
                        {
                            DependencyObject dp = sender as DependencyObject;
                            if (dp == null)
                            {
                                return;
                            }

                            ICommand command = dp.GetValue(_property) as ICommand;

                            if (command == null)
                            {
                                return;
                            }

                            if (command.CanExecute(e))
                            {
                                command.Execute(e);
                            }
                        }

                        /// <summary>
                        /// Listens for a change in the DependencyProperty that we are assigned to, and
                        /// adjusts the EventHandlers accordingly
                        /// </summary>
                        /// <param name="sender"></param>
                        /// <param name="e"></param>
                        public void PropertyChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e)
                        {
                            // the first time the property changes,
                            // make a note of which property we are supposed
                            // to be watching
                            if (_property == null)
                            {
                                _property = e.Property;
                            }

                            object oldValue = e.OldValue;
                            object newValue = e.NewValue;

                            AdjustEventHandlers(sender, oldValue, newValue);
                        }
                    }

                }

             class TextBoxBehaviour
                {
                    public static readonly DependencyProperty TextChangedCommand = EventBehaviourFactory.CreateCommandExecutionEventBehaviour(TextBox.TextChangedEvent, "TextChangedCommand", typeof(TextBoxBehaviour));

                    public static void SetTextChangedCommand(DependencyObject o, ICommand value)
                    {
                        o.SetValue(TextChangedCommand, value);
                    }

                    public static ICommand GetTextChangedCommand(DependencyObject o)
                    {
                        return o.GetValue(TextChangedCommand) as ICommand;
                    }
                 }

1 Ответ

0 голосов
/ 16 марта 2012

Вот проблема. Вы устанавливаете команду в шаблоне ItemTemplate. Таким образом, это привязка к объекту Category, который есть у вас в ListCollectionView. Теперь это объект, который не содержит никаких команд для вашего текста изменен. Что содержит команду для вашего TextChanged, так это DataContext UserControl, и вам нужно привязать его к этому.

Теперь есть способ обойти это, и он называется Ancestor RelativeSource. Поскольку я работаю с silverlight, он может работать по-другому, но эта строка кода должна подойти.

Edit:

Фактическая строка должна быть. это потому, что это, конечно, окно, и вам нужно иметь DataContext (модель представления), а затем свойство TextChanged:

<TextBox ff:TextBoxBehaviour.TextChangedCommand="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}, Path=DataContext.TextChanged}" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...