我想在光标所在的文本框下面插入一个控件:
我在MVVM中有这个代码,文本框是动态创建的:
<ItemsControl IsTabStop="False" ItemsSource="{Binding ListControls}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding RGN_INdex}" Margin="5,5,5,5" FontSize="14" VerticalContentAlignment="Center"/>
<TextBox Style="{StaticResource blankColor}" Text="{Binding RGN}" Grid.Column="1" FontSize="14" VerticalContentAlignment="Center" Margin="0,5,0,5"/>
<Label Grid.Column="2" Content="RSN:" Margin="5,5,5,5" FontSize="14" VerticalContentAlignment="Center"/>
<TextBox Style="{StaticResource blankColor}" Text="{Binding RSN}" Grid.Column="3" FontSize="14" VerticalContentAlignment="Center" Margin="0,5,0,5"/>
<Label Grid.Column="4" Content="SGN:" Margin="5,5,5,5" FontSize="14" VerticalContentAlignment="Center"/>
<TextBox Style="{StaticResource blankColor}" Text="{Binding SGN}" Grid.Column="5" FontSize="14" VerticalContentAlignment="Center" Margin="0,5,0,5"/>
<Label Grid.Column="6" Content="SN:" Margin="5,5,0,5" FontSize="14" VerticalContentAlignment="Center"/>
<TextBox Style="{StaticResource blankColor}" Text="{Binding SN}" Grid.Column="7" FontSize="14" VerticalContentAlignment="Center" Margin="0,5,5,5"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
例如,我有两个文本框:
Textbox1
Textbox2
当我将光标放在Textbox1
并按下按钮时,这将在列表中添加一个项目。然后,视图将填充另一个文本框。
所以在我看来,我会有这个:
Textbox1
Textbox3
Textbox2
在我的XAML中,我有RGN_INdex
- 这将保存创建的控件的索引。
在我看来,当光标聚焦在控件中时,我需要获得RGN_INdex
。但是我该怎么做呢?然后将其传递给命令,以便在找到RGN_INdex
后的列表中插入?但是如何获得所选文本框的RGN_INdex
?
我是MVVM的新手,我无法弄清楚如何使这项工作。
答案 0 :(得分:1)
没有简短的答案,但让我指导您如何做到这一点。
让我先添加缺少的代码:
using Prism.Mvvm;
public class Ctrl
{
public int RGN_Index { get; set; }
public string RGN { get; set; }
public string RSN { get; set; }
public string SGN { get; set; }
public string SN { get; set; }
}
public class TheViewModel : BindableBase
{
public ObservableCollection<Ctrl> ListControls { get { return _listControls; } set { SetProperty(ref _listControls, value); } }
private ObservableCollection<Ctrl> _listControls;
// Constructor
public class TheViewModel()
{
ListControls = new ObservableCollection<Ctrl>()
{
new Ctrl() {RGN_Index=1,RGN="RGN1", RSN="RSN1",SGN="SGN1",SN="SN1" },
new Ctrl() {RGN_Index=2,RGN="RGN2", RSN="RSN2",SGN="SGN2",SN="SN2" }
};
}
}
首先,您需要一个属性/字段来存储VM中当前关注的TextBox
RGN_Index
:
private int SelectedIndex {get; set;} = -1; // only accessed internally, so private is good enough
其次,当您获得光标焦点时,需要更新此选定的索引。让我们在您的VM中定义ICommand:
// Here I am binding using Prism.Commands.DelegateCommand
public ICommand GotFocusCommand {get; private set;} = new Prism.Commands.DelegateCommand<int?>(GotFocus_Execute);
private void GotFocus_Execute(int? index)
{
if(index != null)
SelectedIndex = index.Value;
}
然后,我们需要绑定TextBox
&#39; GotFocus
事件并传递RGN_Index
作为参数。在你的xaml中:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<TextBox Text="{Binding RGN}" Grid.Column="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding Path=DataContext.GotFocusCommand, Mode=OneTime, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding RGN_Index}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
您可以注意到绑定需要RelativeSource
ItemsControl
DataContext
。原因是DataTemplate
DataContext
仅限于ListControl
且Command
未在ListControl
中定义,而是在VM中定义。您可以将命令设为静态,但我将跳过此步骤。
第四,你必须要插入按钮。所以,让我们首先在VM中定义命令:
public ICommand InsertCommand { get; private set; } = new Prism.Commands.DelegateCommand(InsertCommand_Execute);
private void InsertCommand_Execute()
{
if (SelectedIndex > 0)
{
// Insert at the selected index. Note that the Ctrl inserted is just for example
ListControls.Insert(SelectedIndex,
new Ctrl()
{
RGN_Index = ++last_index, // or whatever
RGN = $"RGN{last_index}", // or whatever
RSN = $"RSN{last_index}", // or whatever
SGN = $"SGN{last_index}", // or whatever
SN = $"SN{last_index}" // or whatever
});
}
}
private int last_index = 2; // this is just example. You might not even need this.
然后将此命令绑定到xaml上的按钮:
<Button Content="Insert" Command="{Binding Path=InsertCommand, Mode=OneTime}"/>
完成!
需要考虑的事项: