2017-07-28 35 views
0

我希望文本框中的文本在焦點時被選中。 因此我需要將命令綁定到「GotFocus」事件。特別的是,通過ItemsControl動態創建文本框。 因此,存在對UserControl(View),ItemsControl和Item自身的綁定。當我嘗試將UI元素綁定到CommandParameter時,我剛剛將Items bindet獲取到ItemsControl中的當前項目。WPF MVVM交互綁定到UI元素的CommandParameter

所有綁定除了CommandParameter工作完美..

有人有一個想法如何得到這個工作?

這裏是我的代碼:

XAML

/////// <UserControl/> Information: 
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
x:Name="MainBindingControl" 
/////// 

    <ItemsControl ItemsSource="{Binding MySecondModelList }" Margin="10,10,10,0"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <Grid helper:GridHelper.RowCount="{Binding MyFirstModel.Rows}" helper:GridHelper.ColumnCount="{Binding MyFirstModel.Columns}"> 
       </Grid> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemContainerStyle> 
      <Style> 
       <Setter Property="Grid.Row" Value="{Binding Row}" /> 
       <Setter Property="Grid.Column" Value="{Binding Column}" /> 
      </Style> 
     </ItemsControl.ItemContainerStyle> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <TextBox Margin="25,25,25,25" Height="30" Width="30" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextAlignment="Center" VerticalContentAlignment="Center" > 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="GotFocus"> 
          <i:InvokeCommandAction Command="{Binding ElementName=MainBindingControl, Path=DataContext.TextBoxFocusCommand}" CommandParameter="{Binding RelativeSource={ RelativeSource Self }}"/> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
       <TextBox.Style> 
        <Style TargetType="TextBox"> 
         <Setter Property="Background" Value="OrangeRed" /> 
          <Style.Triggers> 
           <Trigger Property="Text" Value="0"> 
            <Setter Property="Background" Value="Orange" /> 
           </Trigger> 
           <Trigger Property="Text" Value="1"> 
            <Setter Property="Background" Value="White" /> 
           </Trigger> 
           <Trigger Property="Text" Value="2"> 
            <Setter Property="Background" Value="White" /> 
           </Trigger> 
           <Trigger Property="Text" Value="3"> 
            <Setter Property="Background" Value="White" /> 
           </Trigger> 
           <Trigger Property="Text" Value="4"> 
            <Setter Property="Background" Value="White" /> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </TextBox.Style> 
       </TextBox> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

CS

#region TextBoxFocus 
    private ICommand _textBoxFocusCommand; 
    public ICommand TextBoxFocusCommand 
    { 
     get { return _textBoxFocusCommand; } 
     set { _textBoxFocusCommand = value; } 
    } 
    public void TextBoxFocus(object parameter) 
    { 
     var _tmp = parameter as TextBox; 
     if (_tmp != null) 
     { 
      _tmp.SelectAll(); 
     } 
    } 
    #endregion 

模式

public class FirstModel 
    { 
     public int Rows { get; set; } 
     public int Columns { get; set; } 
    } 

public class SecondModel 
    { 
     public int Row { get; set; } 
     public int Column { get; set; } 
     public string Text { get; set; } 
    } 

public class ViewModel 
    { 
     public FirstModel MyFirstModel { get; set; } 
     public ObservableCollection<SecondModel> MySecondModelList { get; set; } 
    } 
+0

爲什麼你想要一個UI元素作爲參數傳遞給ViewModel?這不是MVVM真正的工作原理。 ViewModel對視圖一無所知。 –

+0

如果我不知道哪個TextBox聚焦,我不能將Text Text設置爲選定的文本框。而且因爲我有一個動態創建的List auf TextBoxes,我無法將它們綁定到「真實」屬性。 至少這是我想到的。 –

+0

而ViewModel對特殊的TextBox一無所知。那就對了。 它只是編輯一個隨機的文本框。所以與MVVM沒有衝突。不是嗎? –

回答

0

由於你想要做的只是與視圖相關,我只是將代碼添加到代碼隱藏中,而不是嘗試使用命令並獲取ViewModel中的TextBox。在MVVM中,你絕不應該從ViewModel引用UI組件。但是如果你想要做的只是與View相關,那麼你可以使用代碼隱藏。

所以,TextBox的風格里面,你會:

<EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/> 

然後在用戶控件的代碼隱藏:

private void TextBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    TextBox textBox = sender as TextBox; 
    textBox.SelectAll(); 
} 

您DataTemplate中的完整源代碼然後會是:

<DataTemplate> 
    <TextBox Margin="25,25,25,25" Height="30" Width="30" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextAlignment="Center" VerticalContentAlignment="Center" > 
     <!-- Just erase this block of code 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="GotFocus"> 
       <i:InvokeCommandAction Command="{Binding ElementName=MainBindingControl, Path=DataContext.TextBoxFocusCommand}" CommandParameter="{Binding RelativeSource={ RelativeSource Self }}"/> 
      </i:EventTrigger> 
     </i:Interaction.Triggers>--> 
     <TextBox.Style>        
      <Style TargetType="TextBox"> 
       <EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/> 
       <Setter Property="Background" Value="OrangeRed" /> 
       <Style.Triggers> 
        <Trigger Property="Text" Value="0"> 
         <Setter Property="Background" Value="Orange" /> 
        </Trigger> 
        <Trigger Property="Text" Value="1"> 
         <Setter Property="Background" Value="White" /> 
        </Trigger> 
        <Trigger Property="Text" Value="2"> 
         <Setter Property="Background" Value="White" /> 
        </Trigger> 
        <Trigger Property="Text" Value="3"> 
         <Setter Property="Background" Value="White" /> 
        </Trigger> 
        <Trigger Property="Text" Value="4"> 
         <Setter Property="Background" Value="White" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 
</DataTemplate> 

請注意,在GotFocus事件上調用的TextBox的方法SelectAll()有一個li這些技巧會按預期工作。檢查這個SO問題:How to automatically select all text on focus in WPF TextBox?

+0

據我所知,我沒有被允許在MVVM中使用Code-Behind。但你的解決方案工作正常,所以我會使用它。謝謝! –