gpt4 book ai didi

c# - TextBoxInputMaskBehavior 覆盖值

转载 作者:太空宇宙 更新时间:2023-11-03 10:29:54 24 4
gpt4 key购买 nike

我有一个用于 Ip 地址的 TextBoxInputMaskBehavior,如下所示: enter image description here
和 xaml 代码:

<UserControl x:Class="Customizing.Views.IpRangeFields"
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ig="http://schemas.infragistics.com/xaml"
xmlns:local="clr-namespace:Customizing.Views"
xmlns:net="clr-namespace:System.Net;assembly=System"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:Customizing.Behaviors"
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
x:Name="Uc"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<system:String x:Key="InputMaskIp">000.000.000.000</system:String>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="10" />
<RowDefinition Height="60" />
<RowDefinition Height="10" />
<RowDefinition Height="60" />
<RowDefinition Height="10" />
<RowDefinition Height="60" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2.5*" />
</Grid.ColumnDefinitions>

<Label Grid.Row="0" Grid.Column="0" Content="Start" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<Label Grid.Row="2" Grid.Column="0" Content="End" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<Label Grid.Row="4" Grid.Column="0" Content="Subnet" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />
<Label Grid.Row="6" Grid.Column="0" Content="Gateway" VerticalContentAlignment="Center" FontSize="18"
HorizontalContentAlignment="Center" FontWeight="Bold" />

<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="0" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<TextBox.Text>
<Binding ElementName="Uc" Path="Start" ValidatesOnNotifyDataErrors="True"
UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>

<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="2" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<Binding ElementName="Uc" Path="End" ValidatesOnNotifyDataErrors="True"
UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>

<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="4" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<TextBox.Text>
<Binding ElementName="Uc" Path="Subnet" ValidatesOnNotifyDataErrors="True"
UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>

<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="6" Grid.Column="1"
FontSize="22" Validation.Error="_ValidationError">
<TextBox.Text>
<Binding ElementName="Uc" Path="Gateway" ValidatesOnNotifyDataErrors="True"
UpdateSourceTrigger="PropertyChanged"
NotifyOnValidationError="true">
<Binding.ValidationRules>
<local:IpAddressRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />
</i:Interaction.Behaviors>
</TextBox>

</Grid>
</UserControl>

以及背后的代码:

using System.Globalization;
using System.Net;
using System.Windows;
using System.Windows.Controls;

namespace Customizing.Views
{
/// <summary>
/// Interaction logic for IpRangeFields.xaml
/// </summary>
public partial class IpRangeFields : UserControl
{
public static readonly DependencyProperty StartProperty = DependencyProperty.Register("Start", typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));

public static readonly DependencyProperty EndProperty = DependencyProperty.Register("End", typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));

public static readonly DependencyProperty SubnetProperty = DependencyProperty.Register("Subnet", typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));

public static readonly DependencyProperty GatewayProperty = DependencyProperty.Register("Gateway",
typeof (string),
typeof (IpRangeFields), new PropertyMetadata(null));

// Register the routed event
public static readonly RoutedEvent ErrorEvent =
EventManager.RegisterRoutedEvent("Error", RoutingStrategy.Bubble,
typeof (RoutedEventHandler), typeof (IpRangeFields));

public IpRangeFields()
{
InitializeComponent();
}

public string Start
{
get { return (string) GetValue(StartProperty); }
set { SetValue(StartProperty, value); }
}

public string End
{
get { return (string) GetValue(EndProperty); }
set { SetValue(EndProperty, value); }
}

public string Subnet
{
get { return (string) GetValue(SubnetProperty); }
set { SetValue(SubnetProperty, value); }
}

public string Gateway
{
get { return (string) GetValue(GatewayProperty); }
set { SetValue(GatewayProperty, value); }
}

public event RoutedEventHandler Error
{
add { AddHandler(ErrorEvent, value); }
remove { RemoveHandler(ErrorEvent, value); }
}

private void _ValidationError(object sender, ValidationErrorEventArgs e)
{
RaiseEvent(new RoutedEventArgs(ErrorEvent, sender));
}
}

public class IpAddressRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
IPAddress ip;
if (!IPAddress.TryParse(value.ToString(), out ip))
{
return new ValidationResult(false, "IP address is not valid.");
}

return new ValidationResult(true, null);
}
}
}

我的问题是,正如您在图片中看到的,只有子网字段显示值,而其他三个字段没有。我敢肯定,

<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="0" />

遮盖了三个字段的值,因此看不到值。
令我困惑的是,为什么会出现 subnet 字段的值?我在其他三个字段上做错了什么?

文本框掩码类:

using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace Customizing.Behaviors
{
/// <summary>
/// InputMask for Textbox with 2 Properties: <see cref="InputMask" />, <see cref="PromptChar" />.
/// </summary>
public class TextBoxInputMaskBehavior : Behavior<TextBox>
{
public MaskedTextProvider Provider { get; private set; }

protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObjectLoaded;
AssociatedObject.PreviewTextInput += AssociatedObjectPreviewTextInput;
AssociatedObject.PreviewKeyDown += AssociatedObjectPreviewKeyDown;

DataObject.AddPastingHandler(AssociatedObject, Pasting);
}

protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Loaded -= AssociatedObjectLoaded;
AssociatedObject.PreviewTextInput -= AssociatedObjectPreviewTextInput;
AssociatedObject.PreviewKeyDown -= AssociatedObjectPreviewKeyDown;

DataObject.RemovePastingHandler(AssociatedObject, Pasting);
}

/*
Mask Character Accepts Required?
0 Digit (0-9) Required
9 Digit (0-9) or space Optional
# Digit (0-9) or space Required
L Letter (a-z, A-Z) Required
? Letter (a-z, A-Z) Optional
& Any character Required
C Any character Optional
A Alphanumeric (0-9, a-z, A-Z) Required
a Alphanumeric (0-9, a-z, A-Z) Optional
Space separator Required
. Decimal separator Required
, Group (thousands) separator Required
: Time separator Required
/ Date separator Required
$ Currency symbol Required

In addition, the following characters have special meaning:

Mask Character Meaning
< All subsequent characters are converted to lower case
> All subsequent characters are converted to upper case
| Terminates a previous < or >
\ Escape: treat the next character in the mask as literal text rather than a mask symbol

*/

private void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
{
Provider = new MaskedTextProvider(InputMask, CultureInfo.CurrentCulture);
Provider.Set(AssociatedObject.Text);
Provider.PromptChar = PromptChar;
AssociatedObject.Text = Provider.ToDisplayString();

//seems the only way that the text is formatted correct, when source is updated
var textProp = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof (TextBox));
if (textProp != null)
{
textProp.AddValueChanged(AssociatedObject, (s, args) => UpdateText());
}
}

private void AssociatedObjectPreviewTextInput(object sender, TextCompositionEventArgs e)
{
TreatSelectedText();

var position = GetNextCharacterPosition(AssociatedObject.SelectionStart);

if (Keyboard.IsKeyToggled(Key.Insert))
{
if (Provider.Replace(e.Text, position))
position++;
}
else
{
if (Provider.InsertAt(e.Text, position))
position++;
}

position = GetNextCharacterPosition(position);

RefreshText(position);

e.Handled = true;
}

private void AssociatedObjectPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space) //handle the space
{
TreatSelectedText();

var position = GetNextCharacterPosition(AssociatedObject.SelectionStart);

if (Provider.InsertAt(" ", position))
RefreshText(position);

e.Handled = true;
}

if (e.Key == Key.Back) //handle the back space
{
if (TreatSelectedText())
{
RefreshText(AssociatedObject.SelectionStart);
}
else
{
if (AssociatedObject.SelectionStart != 0)
{
if (Provider.RemoveAt(AssociatedObject.SelectionStart - 1))
RefreshText(AssociatedObject.SelectionStart - 1);
}
}

e.Handled = true;
}

if (e.Key == Key.Delete) //handle the delete key
{
//treat selected text
if (TreatSelectedText())
{
RefreshText(AssociatedObject.SelectionStart);
}
else
{
if (Provider.RemoveAt(AssociatedObject.SelectionStart))
RefreshText(AssociatedObject.SelectionStart);
}

e.Handled = true;
}
}

/// <summary>
/// Pasting prüft ob korrekte Daten reingepastet werden
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Pasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof (string)))
{
var pastedText = (string) e.DataObject.GetData(typeof (string));

TreatSelectedText();

var position = GetNextCharacterPosition(AssociatedObject.SelectionStart);

if (Provider.InsertAt(pastedText, position))
{
RefreshText(position);
}
}

e.CancelCommand();
}

private void UpdateText()
{
//check Provider.Text + TextBox.Text
if (Provider.ToDisplayString().Equals(AssociatedObject.Text))
return;

//use provider to format
var success = Provider.Set(AssociatedObject.Text);

//ui and mvvm/codebehind should be in sync
SetText(success ? Provider.ToDisplayString() : AssociatedObject.Text);
}

/// <summary>
/// Falls eine Textauswahl vorliegt wird diese entsprechend behandelt.
/// </summary>
/// <returns>true Textauswahl behandelt wurde, ansonsten falls </returns>
private bool TreatSelectedText()
{
if (AssociatedObject.SelectionLength > 0)
{
return Provider.RemoveAt(AssociatedObject.SelectionStart,
AssociatedObject.SelectionStart + AssociatedObject.SelectionLength - 1);
}
return false;
}

private void RefreshText(int position)
{
SetText(Provider.ToDisplayString());
AssociatedObject.SelectionStart = position;
}

private void SetText(string text)
{
AssociatedObject.Text = string.IsNullOrWhiteSpace(text) ? string.Empty : text;
}

private int GetNextCharacterPosition(int startPosition)
{
var position = Provider.FindEditPositionFrom(startPosition, true);

if (position == -1)
return startPosition;
return position;
}

#region DependencyProperties

public static readonly DependencyProperty InputMaskProperty =
DependencyProperty.Register("InputMask", typeof (string), typeof (TextBoxInputMaskBehavior), null);

public string InputMask
{
get { return (string) GetValue(InputMaskProperty); }
set { SetValue(InputMaskProperty, value); }
}

public static readonly DependencyProperty PromptCharProperty =
DependencyProperty.Register("PromptChar", typeof (char), typeof (TextBoxInputMaskBehavior),
new PropertyMetadata('_'));

public char PromptChar
{
get { return (char) GetValue(PromptCharProperty); }
set { SetValue(PromptCharProperty, value); }
}

#endregion
}
}

最佳答案

我复制了你的代码,它运行没有错误。

设置值(ipRange 由您控制):

ipRange.Start = "123.456.789.000";
ipRange.End = "123.456.789.000";
ipRange.Subnet = "123.456.789.000";
ipRange.Gateway = "123.456.789.000";

结果:

Screenshot

我认为,绑定(bind)问题或其他问题,但无法控制。

一条评论。将掩码从 000.000.000.000 更改为 000\.000\.000\.000 因为 . 是小数点分隔符(在我的国家/地区是逗号,而不是点,因此您可能会在文化支持方面遇到麻烦。

关于c# - TextBoxInputMaskBehavior 覆盖值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30567155/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com