[英]WPF MVVM Interaction Binding CommandParameter to UI element
I want the text in a TextBox to get selected when the TextBox gets focused. 我希望TextBox获得焦点时选择TextBox中的文本。 Therefore I need to binding a Command to the "GotFocus" event.
因此,我需要将命令绑定到“ GotFocus”事件。 The special thing is, that the TextBox is created dynamically via an ItemsControl .
特殊的是,TextBox是通过ItemsControl动态创建的 。 So there is a binding to the UserControl (View), the ItemsControl and the Item itself.
因此,存在对UserControl(视图),ItemsControl和Item本身的绑定。 When I tried to bind the UI element to the CommandParameter I just got the Model bindet to the current item in the ItemsControl.
当我尝试将UI元素绑定到CommandParameter时,我只是将Model绑定绑定到ItemsControl中的当前项目。
All the bindings are working perfectly except the CommandParameter.. 除CommandParameter之外,所有绑定均正常运行。
Somebody got an idea how to get this working? 有人知道如何使它工作?
Here is my code: 这是我的代码:
XAML 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 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
Models 楷模
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; }
}
Since what you want to do is only related to the view, I'd just add the code in the code-behind, instead of trying to use commands and get the TextBox inside the ViewModel. 由于您要执行的操作仅与视图相关,因此,我只是将代码添加到了代码背后,而不是尝试使用命令并在ViewModel中获取TextBox。 In MVVM you should NEVER reference UI assemblies from the ViewModel.
在MVVM中,您永远不要从ViewModel引用UI程序集。 But it is ok for you to use code-behind if what you are trying to do is only related to the View.
但是,如果您要执行的操作仅与视图相关,则可以使用代码隐藏。
So, inside the style of the TextBox, you would have: 因此,在TextBox样式内,您将具有:
<EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/>
And then in the code-behind of the UserControl: 然后在UserControl的代码背后:
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBox textBox = sender as TextBox;
textBox.SelectAll();
}
The complete code of your DataTemplate would then be: 然后,您的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>
Notice that the method SelectAll() of the TextBox called on GotFocus event has a little trick to work as intended. 请注意,在GotFocus事件上调用的TextBox的SelectAll()方法具有一些可以按预期工作的技巧。 Check this SO question: How to automatically select all text on focus in WPF TextBox?
请检查以下SO问题: 如何自动选择WPF TextBox中焦点上的所有文本?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.