2011-01-07 81 views
1

我'使用MVVM模式構建應用程序。在這個應用程序,我有一個綁定到項目的總彙和屬性包含所選項目的組合框:WPF:更改後重置組合框

<ComboBox ItemsSource="{Binding Path=Persons, Mode=OneTime}" 
      SelectedValue="{Binding Path=SelectedPerson, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

與物品ComboBox的集合被初始化的「指令文本」爲先項目,然後一羣普通的項目:

Persons.Add("Open Person..."); 
Persons.Add("Anders Andersson"); 
Persons.Add("Bengt Bengtsson"); 
Persons.Add("Carl Carlsson"); 
Persons.Add("Daniel Danielsson"); 

我想有這個組合框的行爲是它最初顯示的說明文本(這當然是很容易實現的)。當用戶在組合框中選擇一個人時,應用程序會執行一些操作(打開選定的人員),然後重置爲指令文本。

由於第一以爲這很容易通過具有這種特性的所選項目:

private string _selectedPerson = "Open Person..."; 
public string SelectedPerson 
{ 
    get 
    { 
     return _selectedPerson; 
    } 
    set 
    { 
     if (value != _selectedPerson) 
     { 
      OpenPerson(value); 
      OnPropertyChanged("SelectedPerson"); 
     } 
    } 
} 

我的想法是,當用戶選擇什麼比在ComboBox指令文本一樣,OpenPerson()會用所選值調用,但所選值不會存儲在專用字段(_selectedPerson)中。然後,我觸發PropertyChanged事件,該事件將使ComboBox讀取屬性SelectedPerson的值並更新自身(SelectedValue)。因爲_seletedPerson字段仍然是指令文本,所以ComboBox將自行重置爲該指令文本。

這不行。

其實,一切似乎都按我的預期發生。用正確的參數調用OpenPerson(),然後觸發PropertyChanged事件。但是,GUI的更改ComboBox所顯示的值的操作實際上是在所有這些之後執行的。這意味着無論我將SelectedPerson設置爲何,組合框都將顯示在GUI中選擇的項目。

有沒有一種優雅的方式來解決這個問題?

其實,我已經自己解決了這個問題。但它涉及CodeBehind中的代碼,ViewModel中的兩個標記以及SelectedPerson屬性中的一些令人討厭的代碼。這個解決方案,至少不能令人滿意......;)所以,我希望有人比我更聰明,可以提出更好的解決方案! :)

回答

1

您是否嘗試過爲Combobox創建SelectionChanged處理程序,並將其更改回「Open Person ...」?

甚至是一個組合框的觸發器,將其設置爲Index = 0或什麼?

+0

當然的!使用SelectionChanged處理程序是最簡單的解決方案。我一直在想如何在ViewModel中做到這一點,我從來沒有這樣做過。當然,我更喜歡如果我的解決方案能夠工作,這樣我就不需要我的代碼中的任何代碼,但顯然它不。感謝Ingó! :) – haagel 2011-01-07 12:22:05

0

我剛剛發現這個尋找別的東西,我希望我仍然可以幫助。

我將一個命令綁定到selectionchanged事件,該命令在Viewmodel中定義,因此遵循MVVM模式(後面沒有代碼)。

我使用MVVM光強的框架,所以你需要包括包括混合交互參考如下:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
xmlns:cmd="http://www.galasoft.ch/mvvmlight" 

下面是我如何聲明它在我的XAML:

  <ComboBox Name="idClient" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="2" 
           Style="{StaticResource FTC_DetailComboBox}" 
           ItemsSource="{Binding ClientViewSource.View}" 
           SelectedItem="{Binding client}" 
           SelectedValuePath="idClient" 
           SelectedValue="{Binding idClient, Mode=TwoWay, ValidatesOnDataErrors=True}" 
           DisplayMemberPath="chrCompany" 
           > 
       <i:Interaction.Triggers> 
        <i:EventTrigger EventName="SelectionChanged"> 
         <cmd:EventToCommand Command="{Binding LostFocusValidateCommand}" CommandParameter="idStatus"/> 
        </i:EventTrigger> 
       </i:Interaction.Triggers> 
      </ComboBox> 

這裏是我的viewmodel(在vb.net中)的代碼。RelayCommand是一個簡單的實現的ICommand

Private _LostFocusValidateCommand As RelayCommand(Of String) 

    Public ReadOnly Property LostFocusValidateCommand() As RelayCommand(Of String) 
     Get 
      If _LostFocusValidateCommand Is Nothing Then 
       _LostFocusValidateCommand = New RelayCommand(Of String)(AddressOf LostFocusValidateExecute) 
      End If 
      Return _LostFocusValidateCommand 
     End Get 
    End Property 

    Private Sub LostFocusValidateExecute(sParam As String) 
     ''perform commands here 
    End Sub