文本框应该以特定的格式显示在十六进制文字 [英] TextBox should display text in hexadecimal in a specific format

查看:418
本文介绍了文本框应该以特定的格式显示在十六进制文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的XAML文件的文本框是可编辑的。现在,根据我的文本框项目要求的内容应该只有0-9和A-F(十六进制值)和文本框应该基于十六进制值取输入。

I have a textbox in my xaml file which is editable. Now according to my project requirements content in textbox should only be 0-9 and a-f (hexadecimal values) and textbox should take the input based on hexadecimal values.

Demonstratation:

Demonstratation:

12 AB 32 A5 64

现在,如果我的光标是在年底,我去按Backspace键,它shud因为它在一般的文本框中发生取出值。

Now if my cursor is at the end and i go on pressing backspace, it shud remove the values as it happens in a general text box.

现在如果我的光标在A5的开始,我按下删除键,该值应该成为这样的:

Now If my cursor is at the beginning of a5, and i press "delete key", the value should become like:

12 AB 32 56 4

如果我的光标是在A5的结束,我按下删除键什么都不发生。

If my cursor is at the end of a5 and i press the 'delete key" nothing should happen.

我做了这个成功在我的C ++应用程序如下:

I had done this successful in my C++ application as follows:

void CMSP430CommPanel::textEditorTextChanged (TextEditor& editor)
{

if(&editor == m_texti2cWrite)
{       
    int count = 0;
    int location;

    String text1 = m_texti2cWrite->getText();
    String text = m_texti2cWrite->getText().removeCharacters(" ");
    String hexString = String::empty;   
    int countCaret = m_texti2cWrite->getCaretPosition();

        for(int i=0; i < text.length(); i++)
        {               
            hexString = hexString + String (&text[i], 1);
            if((i+1) % 2 == 0)
            {
                if(i != text.length()-1)
                {
                    hexString = hexString + T(" "); 
                    count ++;               
                }
            }
            count ++;
        }           

        m_texti2cWrite->setText(hexString,false);

        if(text1.length() == m_texti2cWrite->getCaretPosition())
        {
            m_texti2cWrite->setCaretPosition(count);
        }
        else
        {
            m_texti2cWrite->setCaretPosition(countCaret);
        }
}



}

}

其中m_texti2cWrite是给文本框的名称。我如何能实现我的WPF应用程序相同的情况下,这是基于MVVM。我有一个文本框,正如我上面所说这shud需要投入。请帮助!

where m_texti2cWrite is the name given to textbox. How can i implement the same case in my wpf application which is MVVM based. I have a textbox which shud take inputs as I said above. please help!!!

推荐答案

由于您使用的MVVM - 你可以通过的值转换 - 我在这样做,主要是出于好奇了个去 - 这似乎工作得很好,但目前需要每转换器的一个实例控制,因为它是用一个实例变量来缓存最后一次正确的十六进制值 - 我确定你可以配合使用,以验证改进它

Since you are using MVVM - you could do this via a Value Converter - i had a go at doing this, mostly out of curiosity - this seems to work quite well but currently requires an instance of the convertor per control as it is using an instance variable to cache the last known good hex value - im sure you could use it in conjunction with validation to improve it.

更新
好​​吧,这似乎工作(ISH) - 只允许1-9安培; AF,我不得不关闭文本框的选择,因为它是造成奇怪的结果 - 我已经使用了附加的行为来控制光标,有可能是一个更好的方式来做到这一点,但我肯定不知道如何...

Update Okay this seems to work(ish) - allows only 1-9 & A-F, i have had to disable textbox selection as it was causing strange results - i have used an attached behaviour to control the cursor, there may be a better way to do this but i sure dont know how...

的删除行为可以作为你问(如果您删除在对什么都不做的结束)。

The delete behaviour works as you asked (if you delete at the end of a pair it does nothing).

有一出戏:)

更新2

做了一些修改,以得到它一起工作文本选择。

Made some changes to get it to work with text selection.

查看

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.Resources>
        <local:HexStringConverter x:Key="HexConverter"></local:HexStringConverter>
    </Grid.Resources>
    <StackPanel>
        <TextBox local:TextBoxBehaviour.KeepCursorPosition="true"  VerticalAlignment="Center" Width="200" HorizontalAlignment="Center" Text="{Binding HexValue,Mode=TwoWay,Converter={StaticResource HexConverter},UpdateSourceTrigger=PropertyChanged}"></TextBox>

    </StackPanel>
</Grid>




查看后面的代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.DataContext = new MyViewModel();
        InitializeComponent();
    }



视图模型

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;


    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    private string hexValue;
    public string HexValue
    {
        get
        {
            return hexValue;
        }
        set
        {
            hexValue = value;
            OnPropertyChanged("HexValue");
        }
    }


}

十六进制转换

public class HexStringConverter : IValueConverter
{
    private string lastValidValue;
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string ret = null;

        if (value != null && value is string)
        {
            var valueAsString = (string)value;
            var parts = valueAsString.ToCharArray();
            var formatted = parts.Select((p,i)=>(++i)%2==0 ? String.Concat(p.ToString()," ") : p.ToString());
            ret = String.Join(String.Empty,formatted).Trim();
        }


        return ret;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        object ret = null;
        if (value != null && value is string)
        {
            var valueAsString = ((string)value).Replace(" ",String.Empty).ToUpper();
            ret = lastValidValue = IsHex(valueAsString) ? valueAsString : lastValidValue;                
        }

        return ret;
    }


    private bool IsHex(string text)
    {
        var reg = new System.Text.RegularExpressions.Regex("^[0-9A-Fa-f]*$");
        return reg.IsMatch(text);
    }
}



文本框的行为

public static class TextBoxBehaviour
{
    public static bool GetKeepCursorPosition(DependencyObject obj)
    {
        return (bool)obj.GetValue(KeepCursorPositionProperty);
    }

    public static void SetKeepCursorPosition(DependencyObject obj, bool value)
    {
        obj.SetValue(KeepCursorPositionProperty, value);
    }

    // Using a DependencyProperty as the backing store for KeepCursorPosition.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty KeepCursorPositionProperty =
        DependencyProperty.RegisterAttached("KeepCursorPosition", typeof(bool), typeof(TextBoxBehaviour), new UIPropertyMetadata(false, KeepCursorPosition));


    public static int GetPreviousCaretIndex(DependencyObject obj)
    {
        return (int)obj.GetValue(PreviousCaretIndexProperty);
    }

    public static void SetPreviousCaretIndex(DependencyObject obj, int value)
    {
        obj.SetValue(PreviousCaretIndexProperty, value);
    }

    // Using a DependencyProperty as the backing store for PreviousCaretIndex.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PreviousCaretIndexProperty =
        DependencyProperty.RegisterAttached("PreviousCaretIndex", typeof(int), typeof(TextBoxBehaviour), new UIPropertyMetadata(0));


    public static string GetPreviousTextValue(DependencyObject obj)
    {
        return (string)obj.GetValue(PreviousTextValueProperty);
    }

    public static void SetPreviousTextValue(DependencyObject obj, string value)
    {
        obj.SetValue(PreviousTextValueProperty, value);
    }

    // Using a DependencyProperty as the backing store for PreviousTextValue.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty PreviousTextValueProperty =
        DependencyProperty.RegisterAttached("PreviousTextValue", typeof(string), typeof(TextBoxBehaviour), new UIPropertyMetadata(null));

    private static void KeepCursorPosition(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var textBox = sender as TextBox;

        if (textBox != null)
        {
            textBox.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(textBox_PreviewKeyDown);
            textBox.TextChanged += new TextChangedEventHandler(textBox_TextChanged);
            textBox.Unloaded += new RoutedEventHandler(textBox_Unloaded);
        }
        else
        {
            throw new ArgumentException("KeepCursorPosition only available for textboxes");
        }
    }

    static void textBox_Unloaded(object sender, RoutedEventArgs e)
    {
        var textBox = sender as TextBox;
        textBox.PreviewKeyDown -= new System.Windows.Input.KeyEventHandler(textBox_PreviewKeyDown);
        textBox.TextChanged -= new TextChangedEventHandler(textBox_TextChanged);
        textBox.Unloaded -= new RoutedEventHandler(textBox_Unloaded);
    }


    static void textBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        //For some reason our e.Changes only ever contains 1 change of 1 character even if our
        //converter converts it to 2 chars with the additional space - hmmm?
        var textBox = sender as TextBox;
        var previousIndex = GetPreviousCaretIndex(textBox);
        var previousText = GetPreviousTextValue(textBox);

        var previousLen = !String.IsNullOrEmpty(previousText) ? previousText.Length : 0;
        var currentLen = textBox.Text.Length;
        var change = (currentLen - previousLen);

        var newCharIndex = Math.Max(1, (previousIndex + change));

        Debug.WriteLine("Text Changed Previous Caret Pos : {0}", previousIndex);
        Debug.WriteLine("Text Changed Change : {0}", change);
        Debug.WriteLine("Text Changed New Caret Pos : {0}", newCharIndex);

        textBox.CaretIndex = Math.Max(newCharIndex, previousIndex);
        SetPreviousCaretIndex(textBox, textBox.CaretIndex);
        SetPreviousTextValue(textBox, textBox.Text);
    }

    static void textBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        var textBox = sender as TextBox;
        Debug.WriteLine("Key Preview Caret Pos : {0}", textBox.CaretIndex);
        Debug.WriteLine("------------------------");
        SetPreviousCaretIndex(textBox, textBox.CaretIndex);
        SetPreviousTextValue(textBox, textBox.Text);
    }
}

这篇关于文本框应该以特定的格式显示在十六进制文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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