Свяжите TextBox на нажатии клавиши Enter

Проблема в твоих действиях. Это добавляет задачу с ключом payload, но вы пытаетесь связать ее с action.task (которого не существует).

Объект, который будет отправлен в ваш редуктор, будет выглядеть следующим образом:

{
    type: 'ADD_TASK',
    payload: {
        task: 'like it'
    }
}

Вы можете ясно видеть здесь, action.task не существует, но action.payload.task существует. Либо измените объект вокруг, либо измените его так, чтобы вы могли получить к нему доступ в action.task:

const addTask = (task) => ({
    type: 'ADD_TASK',
    task
})

или , измените ваш редуктор:

function tasksReducer(state = initalState, action) {
    switch (action.type) {
        case 'ADD_TASK':
            return {
                ...state,
                tasks: state.tasks.concat([action.payload.task])
            };
        default:
            return state;
    }
}

[ 1115] В будущем: небольшая отладка прошла бы долгий путь (и вообще избежал бы этого вопроса). Простой console.log(action) в верхней части вашего редуктора будет регистрировать вышеупомянутый объект, и вы можете сделать вывод, основываясь на том, почему он пытается добавить неопределенное, почему он не будет работать.

103
задан Bugfinger 16 June 2016 в 00:01
поделиться

3 ответа

Можно сделать себя чистым подходом XAML путем создания присоединенное поведение .

Что-то вроде этого:

public static class InputBindingsManager
{

    public static readonly DependencyProperty UpdatePropertySourceWhenEnterPressedProperty = DependencyProperty.RegisterAttached(
            "UpdatePropertySourceWhenEnterPressed", typeof(DependencyProperty), typeof(InputBindingsManager), new PropertyMetadata(null, OnUpdatePropertySourceWhenEnterPressedPropertyChanged));

    static InputBindingsManager()
    {

    }

    public static void SetUpdatePropertySourceWhenEnterPressed(DependencyObject dp, DependencyProperty value)
    {
        dp.SetValue(UpdatePropertySourceWhenEnterPressedProperty, value);
    }

    public static DependencyProperty GetUpdatePropertySourceWhenEnterPressed(DependencyObject dp)
    {
        return (DependencyProperty)dp.GetValue(UpdatePropertySourceWhenEnterPressedProperty);
    }

    private static void OnUpdatePropertySourceWhenEnterPressedPropertyChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        UIElement element = dp as UIElement;

        if (element == null)
        {
            return;
        }

        if (e.OldValue != null)
        {
            element.PreviewKeyDown -= HandlePreviewKeyDown;
        }

        if (e.NewValue != null)
        {
            element.PreviewKeyDown += new KeyEventHandler(HandlePreviewKeyDown);
        }
    }

    static void HandlePreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            DoUpdateSource(e.Source);
        }
    }

    static void DoUpdateSource(object source)
    {
        DependencyProperty property =
            GetUpdatePropertySourceWhenEnterPressed(source as DependencyObject);

        if (property == null)
        {
            return;
        }

        UIElement elt = source as UIElement;

        if (elt == null)
        {
            return;
        }

        BindingExpression binding = BindingOperations.GetBindingExpression(elt, property);

        if (binding != null)
        {
            binding.UpdateSource();
        }
    }
}

Затем в Вашем XAML Вы устанавливаете InputBindingsManager.UpdatePropertySourceWhenEnterPressedProperty свойство к тому, которое Вы хотите обновить, когда Входят клавиша нажата. Как это

<TextBox Name="itemNameTextBox"
         Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}"
         b:InputBindingsManager.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>

(Просто необходимо удостовериться, что включали xmlns ссылку пространства имен сброса для "b" в корневом элементе файла XAML, указывающего, который когда-либо пространство имен Вы вставляете InputBindingsManager).

130
ответ дан Grhm 24 November 2019 в 04:15
поделиться

Я не полагаю, что существует любой "чистый XAML" способ сделать то, что Вы описываете. Можно настроить привязку так, чтобы она обновила каждый раз, когда текст в TextBox изменяется (скорее чем, когда TextBox теряет фокус) путем установки свойство UpdateSourceTrigger, как это:

<TextBox Name="itemNameTextBox"
    Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}" />

, Если Вы устанавливаете UpdateSourceTrigger на "Явный" и затем обработали событие TextBox's PreviewKeyDown (ищущий клавишу Enter) затем, Вы могли достигнуть того, что Вы хотите, но это потребовало бы кода - позади. Возможно, своего рода приложенное свойство (подобный моему свойство EnterKeyTraversal) woudld работает на Вас.

46
ответ дан Matt Hamilton 24 November 2019 в 04:15
поделиться

Вы можете легко создать свой собственный элемент управления, унаследованный от TextBox, и повторно использовать его в вашем проекте.

Что-то похожее на это должно сработать:

public class SubmitTextBox : TextBox
{
    public SubmitTextBox()
        : base()
    {
        PreviewKeyDown += new KeyEventHandler(SubmitTextBox_PreviewKeyDown);
    }

    void SubmitTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            BindingExpression be = GetBindingExpression(TextBox.TextProperty);
            if (be != null)
            {
                be.UpdateSource();
            }
        }
    }
}

Может быть способ обойти этот шаг , но в противном случае вы должны выполнить привязку следующим образом (используя Explicit):

<custom:SubmitTextBox
    Text="{Binding Path=BoundProperty, UpdateSourceTrigger=Explicit}" />
25
ответ дан 24 November 2019 в 04:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: