Конвертеры вызываются при каждом нажатии клавиши, а не в конце пользовательского ввода - PullRequest
6 голосов
/ 25 января 2012

У меня проблема с вводом данных с момента перехода на .NET 4.0. В моей сетке Xceed 3.7 пользователь имел обыкновение вводить значение в ячейку, и когда они щелкали или нажимали клавишу ввода, вызывался метод привязанного конвертера ConvertBack, анализирующий значение пользовательского ввода и сохраняющий в желаемом формат.

Теперь внезапно, это происходит при каждом нажатии клавиши - что вызывает огромную проблему, потому что если пользователь стирает число и начинает набирать другое, (скажем, -100), как только когда они вводят отрицательный знак, преобразование запускается и выдает исключение, потому что «-» не является строкой для синтаксического анализа, и значение возвращается.

Я думаю, что проблема довольно ясна, поэтому сейчас я вставлю код.

Столбцы для пользовательского ввода выглядят следующим образом:

<xcdg:DataGridControl x:Name="AggCatGrid01"
      ItemsSource="{Binding Source={StaticResource myDataSource}}" >
<xcdg:DataGridControl.Columns>
      ...
      <xcdg:Column VisiblePosition="0" FieldName="SomeValue" Title="Some Value"
                   CellEditor="{StaticResource PercentageEditor}"
                   CellContentTemplate="{StaticResource EditablePercent2CellContentTemplate}" />

Все блоки данных имеют одинаковый стиль:

<Style x:Key="{x:Type xcdg:DataGridControl}" TargetType="{x:Type xcdg:DataGridControl}">
    <Setter Property="UpdateSourceTrigger" Value="CellEndingEdit"/>
    <Setter Property="AutoCreateColumns" Value="False"/>
    <Setter Property="EditTriggers" Value="BeginEditCommand, CellIsCurrent, ActivationGesture"/>
    <Setter Property="CellEditorDisplayConditions" Value="CellIsCurrent"/>
    <Setter Property="NavigationBehavior" Value="CellOnly"/>

Обратите внимание, что UpdateSourceTrigger установлено на CellEndingEdit. Я бы подумал, что это именно здесь и будет отвечать за то, когда вызовут конвертеры и обновят значение привязки. Какие бы элементы управления не менялись, просто переключаясь на .NET4.

Вот шаблон данных для столбца, который вы видели выше:

<!-- Styles used when editable cells are being edited. -->
<xcdg:CellEditor x:Key="PercentageEditor">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
                                    Text="{xcdg:CellEditorBinding Converter={StaticResource EditablePercentageConverter}}" />
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>

Я думаю, что сам код конвертера не имеет значения, поэтому я опущу его, если он не будет запрошен. Проблема в том, что он вызывается при каждом нажатии клавиши.

Если бы вы могли пролить свет на это, я был бы в восторге. Я имею в виду, что мне, возможно, придется откатить все свои усовершенствования .NET 4.0 или отложить мой следующий выпуск более чем на месяц, переписав все мои наборы данных, чтобы больше не использовать xceed, если для этого нет решения. Спасибо, ребята.


Обновление # 1

Я действительно придумал умеренно умный обходной путь (по моему скромному мнению), где я ввел фиктивный текстовый блок для хранения xceed CellEditorBinding, который заставляет нас использовать в табличке данных. Затем я изменил свой элемент управления вводом для привязки к текстовому свойству текстового блока, а не к CellEditorBinding напрямую, что позволило мне указать свой собственный режим привязки. Здесь я смог установить режим «lostFocus», и основная проблема была решена! Конвертер больше не вызывается при каждом нажатии клавиши, а только когда пользователь покидает ячейку или нажимает клавишу ввода.

<xcdg:CellEditor x:Key="PercentageEditor">
    <xcdg:CellEditor.EditTemplate>
        <DataTemplate>
            <Grid>                        
                <TextBlock x:Name="bind_source" Text="{xcdg:CellEditorBinding}" Visibility="Collapsed"/>
                <xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
                    Text="{Binding ElementName=bind_source, Path=Text, Mode=TwoWay, UpdateSourceTrigger=LostFocus, Converter={StaticResource EditablePercentageConverter}}" />
            </Grid>
        </DataTemplate>
    </xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>

Как вы можете себе представить, этот слой косвенности вызвал несколько других незначительных проблем, таких как нарушение проверки. Как ни странно, теперь, когда пользователь вводит недопустимые данные, преобразователь выдает исключение, которое xceed перехватывает и использует для включения шаблона ошибки ячейки, но исправление ошибки и нажатие клавиши ввода больше не работают. Единственная опция пользователя - нажать клавишу ESC, в результате чего значение ячейки вернется и потеряет фокус, прежде чем они смогут исправить свой ввод.

User must hit ESC in this situation to continue editing cells. Simply clicking away or changing the value back to something valid doesn’t work.

Я все еще надеюсь на более элегантное решение, которое исправит это.


Обновление № 2

Я нашел разработчика на форумах поддержки Xceed, который представил ту же проблему, что и я, в этом посте: http://silverlightdatagrid.com/CS/forums/permalink/31548/31516/ShowThread.aspx#31516.

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

К сожалению, решение не было предложено. Он действительно представил стратегию более элегантного изменения триггера источника обновлений, которую я смог принять, но у меня все еще есть проблема с ошибкой проверки, замораживающей ячейку, пока пользователь не нажмет ESC.

<xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
     Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=xcdg:DataCell}, 
                    Path=Content, UpdateSourceTrigger=LostFocus, 
                    Converter={StaticResource EditablePercentageConverter}}" />

Обновление № 3

Я подтвердил, что при обновлении до Xceed DataGrid версии 4.3 (в пробном режиме) проблема исчезла сама по себе, так как в этой версии Xceed обновил свою xcdg:CellEditorBinding UpdateSourceTrigger несовместимость с .Net4. 0. Однако, поскольку лицензия на Xceed включает в себя только 6 месяцев обновлений исправлений ошибок, прежде чем вам придется платить за новую лицензию ( нелепо ), и я не вижу ни одной компании, уполномочивающей возмутительно одного разработчика за 1200 долларов плата за использование последней версии Xceed dll только для этой незначительной ошибки, я все еще буду стремиться найти полный обход в версии 3.7 Xceed. Я представлю это «решение» для разработчиков, у которых есть доступ к деньгам.

Как оказалось, обновление до 4.3 не решило проблему. Это только потому, что я забыл отказаться от своих предыдущих изменений. Даже в последней версии Xceed до сих пор не выставил свойство UpdateSourceTrigger на CellEditorBinding.

Ответы [ 2 ]

3 голосов
/ 31 января 2012

Решение:

<xcdg:AutoSelectTextBox Style="{StaticResource DefaultAutoSelectTextBox}"
     Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=xcdg:DataCell}, 
                    Path=Content, UpdateSourceTrigger=LostFocus, 
                    Converter={StaticResource EditablePercentageConverter}}" />

Нет другого способа сделать это.Если вы не используете последнюю версию Xceed, это также приведет к ошибкам проверки, но в последней версии использование этого нового пути привязки работает отлично.Я все еще думаю, что это хак, и, надеюсь, xceed поймет, что ему необходимо предоставить еще несколько свойств для CellEditorBinding.

0 голосов
/ 25 января 2012

Я не знаю элементов управления XCeed, так что это просто обоснованное предположение.

Лично я бы поместил UpdateSourceTrigger в объявление привязки, как это делается в обычном элементе управления .NET:

Text="{xcdg:CellEditorBinding Converter={StaticResource EditablePercentageConverter}, UpdateSourceTrigger=CellEndingEdit}"

Кроме того, поскольку элемент управления является коммерческим, вы должны иметь право на некоторую техническую поддержку от XCeed.

...