【问题标题】:How to automatically change text in a silverlight textbox?如何自动更改 Silverlight 文本框中的文本?
【发布时间】:2012-10-23 20:41:22
【问题描述】:

我在 silverlight 5 项目中使用 MVVM/Caliburn.Micro,我需要自动将用户在 silverlight 文本框中输入的文本更改为大写。

首先,我认为我可以将 ViewModel 上的支持变量设置为大写,并且双向绑定会更改文本。那没有用(尽管我相信如果我使用失去焦点事件会这样做,但我不能这样做,因为我还必须为 KeyUp 做其他事情,并且附加两个事件会导致 xaml 错误)

由于这不起作用,我尝试在 KeyUp 事件上调用方法。这在技术上有效,但由于它正在替换文本,因此会将光标放回开头,因此用户最终会向后输入。

这似乎是相当简单的功能 - 我如何将用户键入的文本转换为大写?我错过了一些简单的东西吗?

这是我现有的代码。 Xaml:

<TextBox x:Name="SomeName" cal:Message.Attach="[Event KeyUp] = [Action ConvertToUppercase($eventArgs)]" />

查看模型:

public void ConvertToUppercase(System.Windows.Input.KeyEventArgs e)
{
     SomeName = _someName.ToUpper();
     //Other code that doesn't concern uppercase
}



编辑替代解决方案: McAden 提出了一个很好的通用解决方案。大约在同一时间,我还意识到有一个替代解决方案(只需将文本框作为参数传递给大写方法并移动光标),所以这里也是代码:

xaml:

<TextBox x:Name="SomeName" cal:Message.Attach="[Event KeyUp] = [Action ConvertToUppercase($source, $eventArgs)]; [Event KeyDown] = [Action DoOtherStuffThatIsntQuestionSpecific($eventArgs)]" />

cs方法:

public void ConvertToUppercase(TextBox textBox, System.Windows.Input.KeyEventArgs e)
{
    //set our public property here again so the textbox sees the Caliburn.Micro INPC notification fired in the public setter
    SomeName = _someName.ToUpper();

    //move the cursor to the last so the user can keep typing
    textBox.Select(SomeName.Length, 0);
}

当然还有 cs 标准 Caliburn.Micro 属性:

private String _someName = "";
public String SomeName
{
    get
    {
        return _someName;
    }
    set
    {
        _someName = value;
        NotifyOfPropertyChange(() => SomeName);
    }
}

【问题讨论】:

  • @Silvermind,-这是我首先尝试的(完全像 devdigital 的建议答案),但它并没有反映 UI 的变化
  • @McAden - 我看到了那个答案,但就像我说的那样,不幸的是,我还有一些其他代码必须在按键时执行,并且在 xaml 中添加两个事件不会编译,所以这似乎没有成为一种选择
  • 您可以将两个 EventTrigger 附加到同一个事件上。以我的回答为例。

标签: c# silverlight xaml mvvm caliburn.micro


【解决方案1】:

here 所述,创建一个 ToUpper EventTrigger。还为您尝试完成的任何其他功能创建另一个。在 xaml 中添加它们:

<TextBox Text="{Binding SomeName, Mode=TwoWay}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="TextChanged">
            <myBehaviors:UpperCaseAction/>
        </i:EventTrigger>
        <i:EventTrigger EventName="TextChanged">
            <myBehaviors:MyOtherAction/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

编辑:我已经使用以下方法对这个解决方案进行了全面测试(不涉及代码隐藏

大写动作:

public class UpperCaseAction : TriggerAction<TextBox>
{
    protected override void Invoke(object parameter)
    {
        var selectionStart = AssociatedObject.SelectionStart;
        var selectionLength = AssociatedObject.SelectionLength;
        AssociatedObject.Text = AssociatedObject.Text.ToUpper();
        AssociatedObject.SelectionStart = selectionStart;
        AssociatedObject.SelectionLength = selectionLength;
    }
}

其他操作:

public class OtherAction : TriggerAction<TextBox>
{
    Random test = new Random();

    protected override void Invoke(object parameter)
    {
        AssociatedObject.FontSize = test.Next(9, 13);
    }
}

XAML 命名空间(TestSL 在这种情况下是我的测试项目的命名空间 - 适当使用你的命名空间):

xmlns:local="clr-namespace:TestSL"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

XAML 文本框

<Grid x:Name="LayoutRoot" Background="LightGray" Width="300" Height="200">
    <TextBox TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10" Width="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="TextChanged">
                <local:UpperCaseAction />
            </i:EventTrigger>
            <i:EventTrigger EventName="TextChanged">
                <local:OtherAction />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBox>
</Grid>

【讨论】:

  • 好的,我之前做错了,但我现在调用了多个事件触发器。如果我继续使用 KeyUp 事件,使用多个触发器仍然会导致相同的问题。如果我切换到使用 TextChanged 我会遇到问题(没有抛出错误,但输入的文本会消失),因为我相信只有在没有 MVVM 的情况下才能工作(您指出的解决方案使用代码隐藏,而不是 View 和 ViewModel)。
  • 我发给你的链接显示了代码隐藏,如果你想这样做的话,但链接显示了一个 MVVM 示例。
  • 哇,感谢所有的工作!我编辑了我的问题以显示我的问题的最简单解决方案,但我更喜欢这个,因为它更通用,并且将来可能会更容易让人们关注这个问题
  • 奇怪,那个人的答案去哪儿了?好像他从来没有评论或发布过答案
【解决方案2】:

UpperCaseConverter.cs:

namespace MyProject.Converters
    {
        /// <summary>
        /// A upper case converter for string values.
        /// </summary>
        public class UpperCaseConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return ConvertToUpper(value);
            }

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return ConvertToUpper(value);
            }

            private string ConvertToUpper(object value)
            {
                if (value != null)
                {
                    return value.ToString().ToUpper();
                }
                return null;
            }
        }
    }

AppResources.xaml:

<ResourceDictionary
    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:conv="clr-namespace:MyProject.Converters;assembly=MyProject"
    mc:Ignorable="d"
    >

    <!-- Converters -->
    <conv:UpperCaseConverter x:Key="UpperCaseConverter"/>

</ResourceDictionary>

MyFormView.xaml:

<UserControl>
    <TextBox Text="{Binding myText, Mode=TwoWay, Converter={StaticResource UpperCaseConverter}}" />
</UserControl>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多