2011-04-26 29 views
0

我不知道如何问这个问题,但是在这里。我有一个WPF窗口,它有一个响应TextBox的TextChanged事件的委托。当我将数据加载到窗口中,然后订阅我的控制器类到该事件时,委托处理程序方法被调用。为什么委托订阅者在事件通过后被调用?

顺序是这样的。 1.创建窗口 2.加载该窗口的数据。 3.使用TextDidChange方法订阅窗口的TextChanged事件。

在这种情况下,即使在步骤2中发生“事件”,我的TextDidChange方法也会被调用。是否会出现这种预期行为?如果不是,会发生什么?编号: 下面是相关的代码。我没有发布UserControl的事件处理,因为它是样板(如果委托!= null,则调用委托)。

从控制器构造:

public ServiceRequestVM(Boolean isDataSourceProd, codExistServiceRequestSearchType requestIdOrMapNo, String aMapNumber, Decimal aRequestId) { 
     //create the schema and load any necessary data 
     _sroc = new ServiceRequestOracleController(); 
     _sroc.IsProd = isDataSourceProd; 
     _isProd = isDataSourceProd; 
     _isNewRequest = false; 
     _searchType = requestIdOrMapNo; 
     createSchema(); 

     if (requestIdOrMapNo == codExistServiceRequestSearchType.MapNumber) { 
      loadMatchingRequest(aMapNumber); 
     } else { 
      loadMatchingRequest(aRequestId); 
     } 
     Decimal _reqId = (Decimal)_serviceRequestTable.Rows[0]["REQUESTID"]; 
     loadNotesForRequest(_reqId); 
     loadTagsForRequest(_reqId); 
     Decimal _custId = (Decimal)_serviceRequestTable.Rows[0]["CUSTOMERID"]; 
     getNameForCustomerAndSetCustomerIdForRequest(_custId); 

     //configure the UI 
     configureUI(); 
     customerListBoxVisibility = Visibility.Hidden; 
     tagListBoxVisibility = Visibility.Hidden; 

     //create the view (a UserControl) 
     _serviceRequestView = new ServiceRequestView(); 
     _serviceRequestView.DataContext = this; 

     //load customers and tags 
     loadCustomers(); 
     loadTags(); 

     _shouldListBoxesBeSeen = false; 

     //subscribe to delegates 
     subscribeToRequestDelegates(); 
    } 

的subscribeToRequestDelegates方法

private void subscribeToRequestDelegates() { 
     _serviceRequestView.addNoteButtonWasClicked += new ServiceRequestView.AddNoteButtonWasClickedHandler(addNote); 
     _serviceRequestView.addTagButtonWasClicked += new ServiceRequestView.AddTagButtonWasClickedHandler(addTag); 
     _serviceRequestView.locateButtonWasClicked += new ServiceRequestView.LocateButtonWasClickedHandler(locateMap); 
     _serviceRequestView.openButtonWasClicked += new ServiceRequestView.OpenButtonWasClickedHandler(openMap); 
     _serviceRequestView.saveButtonWasClicked += new ServiceRequestView.SaveButtonWasClickedHandler(saveRequest); 
     _serviceRequestView.noteWasDoubleClicked += new ServiceRequestView.NoteWasDoubleClickedHandler(openSelectedNote); 
     _serviceRequestView.dateCompletedLostFocus += new ServiceRequestView.DateCompletedLostFocusHandler(dateCompletedDidChange); 
     _serviceRequestView.titleLostFocus += new ServiceRequestView.TitleLostFocusHandler(titleDidChange); 
     _serviceRequestView.customerTextChanged += new ServiceRequestView.CustomerTextChangedHandler(customerTextDidChange); 
     _serviceRequestView.selectedCustomerChanged += new ServiceRequestView.SelectedCustomerChangedHandler(selectedCustomerDidChange); 
     _serviceRequestView.tagTextChanged += new ServiceRequestView.TagTextChangedHandler(tagTextDidChange); 
     _serviceRequestView.selectedTagChanged += new ServiceRequestView.SelectedTagChangedHandler(selectedTagDidChange); 
     _serviceRequestView.tagTextLostFocus += new ServiceRequestView.TagTextLostFocusHandler(tagTextLostFocus); 
     _serviceRequestView.customerTextLostFocus += new ServiceRequestView.CustomerTextLostFocusHandler(customerTextLostFocus); 
     _serviceRequestTable.ColumnChanged += new DataColumnChangeEventHandler(serviceRequestTableColumnValueDidChange); 
    } 
+0

这是一个奇怪的行为。你能提供你的代码吗? – IVerzin 2011-04-27 07:36:39

回答

0

我不能告诉你肯定什么WPF是干什么的,但在Windows引擎盖下,控件的文字通常通过向窗口发送消息来更新。这放在应用程序的消息队列中,并且只在UI线程处理消息时才处理 - 因此,如果控件正在由UI线程处理,那么您必须完成初始化并将控制返回到主消息处理循环(或调用DoEvents()),然后控件将接收并处理消息。即它以异步方式发生。 (您也可以将消息“发布”给控件,该控件在返回到您的代码之前等待控件处理该消息,但可能/有可能​​WPF不以这种方式调用它)

最简单解决方法是把“保护”变到类,以避免反应“内部”电话,并让您的事件处理程序忽略的事件时,它被设置:

bool suppressTextChanged; 

void Initialize() 
{ 
    suppressTextChanged = true; 
    control.SetText("abcd"); 
    suppressTextChanged = false; 
    ... 
} 

void Control_TextChanged(object sender, EventArgs e) 
{ 
    if (suppressTextChanged) return; 
    ... 
} 

这是一个丑陋,但有效的解决方案。令人遗憾的是,Windows从未提供区分用户驱动事件的方式(例如,用户在控件中编辑它的文本已更改)和内部事件(由程序在内部更新控件驱动) - 尽管对于某些事件,您可以使用“发件人”来确定事件的来源,以确定它是如何触发的。

+0

谢谢。这就是我所害怕的。我得出了关于后卫变量的相同结论,但那很糟糕,我想我不得不错过一些东西。多么痛苦。再次感谢。 – Shawn 2011-04-28 17:18:08

相关问题