1. 使用Mvvmlight中的EventToCommand, Mvvmlight对System.Windows.Interactivity.dll的某些方面进行的扩展
view:
<StackPanel DockPanel.Dock="Top">
<TextBlock Text="传递原事件参数" FontWeight="Bold" FontSize="12" Margin="0 5 0 5"></TextBlock>
<DockPanel>
<StackPanel DockPanel.Dock="Left" Width="240" Orientation="Horizontal">
<Border BorderBrush="{StaticResource PrimaryBrush}">
<TextBlock Text="拖拽上传" Width="100" Height="50" AllowDrop="True"
Style="{StaticResource TextBlockDefaultWarning}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Drop">
<mvvm:EventToCommand PassEventArgsToCommand="True" Command="{Binding DropCommnad}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</Border>
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<TextBlock Text="{Binding FilePath,StringFormat='获取地址:{0}'}"></TextBlock>
</StackPanel>
</DockPanel>
</StackPanel>
viewmodel
private RelayCommand<DragEventArgs> dropCommand;
public RelayCommand<DragEventArgs> DropCommnad
{
get
{
if (dropCommand == null)
{
dropCommand = new RelayCommand<DragEventArgs>(arg => ExecuteDrop(arg));
}
return dropCommand;
}
set { dropCommand = value; }
}
private void ExecuteDrop(DragEventArgs e)
{
Array array = (Array) e.Data.GetData(DataFormats.FileDrop);
FilePath = array.GetValue(0).ToString();
}
2. 使用HandyControl实现的HandyControl.Interactivity
view
<ListBoxItem>
<hc:Interaction.Triggers>
<hc:EventTrigger EventName="Selected">
<hc:EventToCommand Command="{Binding MenuItemSelectCommand}" CommandParameterValue="Pages/LogPage.xaml"/>
</hc:EventTrigger>
</hc:Interaction.Triggers>
<RadioButton Style="{StaticResource RadioMenuButton}"
IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Mode=TwoWay}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Text="" FontFamily="/Resources/Fonts/#iconfont" VerticalAlignment="Center"/>
<TextBlock Margin="15 0 0 0" Text="运行日志" VerticalAlignment="Center"/>
</StackPanel>
</RadioButton>
</ListBoxItem>
viewmodel
public RelayCommand<string> MenuItemSelectCommand =>
new RelayCommand<string>(x =>
{
//PageUri = x;
CurrentContent = FrameContents[x];
if (CurrentContent.DataContext is IPageVisit visit)
{
visit.OnEnter(ServiceLocator.Current.GetInstance<MyContext>());
}
});
3. 使用Interaction.Bahaviors, 下面现实一个Bahavior让ListBox滚动到当前添加内容
view
<Grid Grid.Row="1" Margin="0 0 0 12">
<ListBox ItemsSource="{Binding Logs}" Background="Transparent" HorizontalContentAlignment="Stretch" Margin="3,3,3,3"
ScrollViewer.CanContentScroll="True">
<hc:Interaction.Behaviors>
<bhv:ScrollIntoBehavior/>
</hc:Interaction.Behaviors>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Background="Transparent">
<md:PackIcon Kind="{Binding icon}" Width="26" Height="26" VerticalAlignment="Center" Margin="8 0"/>
<TextBlock Text="{Binding content}" TextAlignment="Left" TextWrapping="Wrap"
Foreground="{Binding color}" Margin="0 0 6 0" VerticalAlignment="Center" Background="Transparent"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ScrollIntoBehavior
public class ScrollIntoBehavior: Behavior<ListBox>
{
protected override void OnAttached()
{
ListBox listBox = AssociatedObject;
// 滚动条定位在底部
listBox.IsVisibleChanged += ListBox_IsVisibleChanged;
((INotifyCollectionChanged)listBox.Items).CollectionChanged += OnListBox_CollectionChanged;
}
protected override void OnDetaching()
{
ListBox listBox = AssociatedObject;
listBox.IsVisibleChanged -= ListBox_IsVisibleChanged;
((INotifyCollectionChanged)listBox.Items).CollectionChanged -= OnListBox_CollectionChanged;
}
private void ListBox_IsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
{
ListBox listBox = AssociatedObject;
if ((bool) e.NewValue)
{
int count = listBox.Items.Count;
if (count > 0)
{
listBox.ScrollIntoView(listBox.Items[count - 1]);
}
}
}
private void OnListBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
ListBox listBox = AssociatedObject;
if (e.Action == NotifyCollectionChangedAction.Add)
{
// scroll the new item into view
listBox.ScrollIntoView(e.NewItems[0]);
}
}
}
4. 在Mvvm下有时候需要在viewmodel与view中的控件交互/操作,可以使用绑定、Bahavior来提供一定程度的方便, vs2017/vs2019中Interaction已经独立出来一个Nuget
地址: https://github.com/Microsoft/XamlBehaviorsWpf
XamlBehaviorsWpf还有丰富的例子参考