C# - MVVM在Handler中处理调用事件处理程序的方法

时间:2016-09-27 16:29:30

标签: c# wpf xaml

我遇到了一个简单的控制处理程序在该处理程序中被调用的情况,这对我来说不是一个新问题,但我的简单解决方案没有通过代码审查。我搜索了类似的SO问题,发现了几个类似的问题,但我不确定它们是否是最好的解决方案。

我在网格控件上有一个简单的文本框,用于搜索数据网格中显示的大型数据集中的行。计划是使用回车作为搜索的触发器,因此" AcceptsReturn"被设定为" True"在文本框中。简单的MainWindow.xaml:

<Window x:Class="TestXaml.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="100" Width="250">
<Grid x:Name="LayoutRoot" Background="White"  Height="100" Width="200">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="60" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="80" />
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0" Grid.Column="0" Name="GoToLabel" Content="Go To Packet ID:" Margin="12, 0, 0, 0"/>
    <TextBox Grid.Row="0" Grid.Column="1" Name="GoToTarget" Width="75" TextChanged="GoToTarget_TextChanged" AcceptsReturn="True"/>
</Grid>

MainWindow.xaml.cs:

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows;  
using System.Windows.Controls;  

namespace TestXaml  
{  
    class SomeDataViewModel  
    {  
        public SomeDataViewModel() { }  
        public bool PacketIndexFor(int packetId, ref int packetIndex)  
        {  
            packetIndex = packetId;  // Just a dummy.  
            return true;  
        }  
    }  

    /// <summary>  
    /// Interaction logic for MainWindow.xaml  
    /// </summary>  
    public partial class MainWindow :   
    {  
        private SomeDataViewModel someDataViewModel;  // The data viewmodel.  
        private bool inGoToTarget = false;  // Stop recursion into goToTarget_TextChanged.  

        public MainWindow()  
        {  
            InitializeComponent();  
        }  

        private void GoToTarget_TextChanged(object sender, TextChangedEventArgs e)  
        {  
            if (inGoToTarget)  // If we are already handling a text-changed event, get out.  
            {  
                return;  
            }  

            inGoToTarget = true;  
            TextBox goToTarget = sender as TextBox;  
            if (null == goToTarget)  
            {  
                inGoToTarget = false  
                return;  
            }  

            if (String.IsNullOrEmpty(goToTarget.Text))  
            {  
                inGoToTarget = false;  
                return;  
            }  

            string enteredTextNoReturn = goToTarget.Text;  
            if (-1 != goToTarget.Text.IndexOf("\r\n"))  
            {  
                enteredTextNoReturn = goToTarget.Text.Substring(0, goToTarget.Text.Length - 2);  // Strip "\r\n"  
            }  

            if (String.IsNullOrEmpty(enteredTextNoReturn))  // Was just carriage return.  
            {  
                // Next line will cause a call to GoToTarget_TextChanged from inside GoToTarget_TextChanged.  
                goToTarget.Text = "";  // Get rid of carriage return.  
                inGoToTarget = false;  
                return;  
            }  

            goToTarget.Text = enteredTextNoReturn;  // Get rid of the carriage return.  

            int packetId = -1;  
            if (int.TryParse(enteredTextNoReturn, out packetId))  
            {  
                int packetIndex = -1;  
                if (someDataViewModel.PacketIndexFor(packetId, ref packetIndex))  
                {  
                    // Set a slider or control value that will make the requested packet display.  
                }  
            }  

            inGoToTarget = false;  
        }  
    }  
}  

注意到&#34;解决&#34;我的问题,我刚给课程添加了一个bool,&#34; inGoToTarget&#34;并设置/取消设置它,以便如果我在处理程序中并尝试重新输入它,处理程序将只返回。

意识到重新进入处理程序的调用发生在处理程序内部,因此在同一个线程中,使用.Net 4.5或更高版本避免此问题的最佳实践方法是什么?

我&#34;修复&#34;通过完全避免它 - 我决定在输入数字时我喜欢发生的行为,所以刚刚删除了&#34; AcceptsReturn&#34;属性。这意味着我可以删除检查回车的代码,并避免在处理程序内设置值。

0 个答案:

没有答案