Défilement de la souris ne fonctionne pas dans un rouleau spectateur avec wpf grille de données supplémentaires et des éléments d'INTERFACE utilisateur
Je suis à essayer de comprendre comment obtenir le défilement de la souris de travail sur une fenêtre wpf avec un scrollviewer et un datagrid en son sein. WPF et C# code est ci-dessous
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Border Name="DataGridBorder" BorderThickness="2" Margin="1" CornerRadius="4" BorderBrush="#FF080757">
<dg:DataGrid AutoGenerateColumns="False" Name="ValuesDataGrid"
BorderThickness="0" CanUserResizeColumns="True" FontWeight="Bold" HorizontalScrollBarVisibility="Auto"
CanUserReorderColumns="False" IsReadOnly="True" IsTextSearchEnabled="True" AlternationCount="2"
SelectionMode="Extended" GridLinesVisibility="All"
HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserSortColumns="False"
RowDetailsVisibilityMode="Collapsed" SelectedIndex="0"
RowStyle="{StaticResource CognitiDataGridRowStyle}"
>
<dg:DataGrid.Columns>
<dg:DataGridTemplateColumn Header="Title" >
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=Name}" FontWeight="Normal" />
</StackPanel>
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
</dg:DataGrid.Columns>
</dg:DataGrid>
</Border>
</Grid>
<Button Grid.Row="1" Height="90" >hello world</Button>
</Grid>
</ScrollViewer>
et le code C# est comme suit
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
initialize();
}
public void initialize()
{
ObservableCollection<MyObject> testList = new ObservableCollection<MyObject>();
for (int i = 0; i < 20; i++)
{
MyObject my = new MyObject("jack " + i);
testList.Add(my);
}
ValuesDataGrid.ItemsSource = testList;
}
}
public class MyObject
{
public string Name { get; set; }
public MyObject(string name)
{
Name = name;
}
}
Le problème, je suis confronté est que lors de l'utilisation de la souris pour faire défiler, il fonctionne très bien quand il est sur le bouton, mais dès que je bouge le pointeur de la souris sur la grille et essayez de faire défiler, rien ne se passe. Je suis en mesure de déplacer la barre de défilement de la scrollviewer directement. Je suis encore un wpf novice sorte que toute aide sur la façon d'obtenir le défilement de la souris pour le travail sur le contrôle datagrid serait appréciée. Je devine il devrait être assez facile solution pour cela, mais je n'ai pas été en mesure de le comprendre
- J'ai exactement le même problème, cependant les solutions ci-dessous ne fonctionnent pas très bien dans une application MVVM. Notre architecte ne veux pas de code dans les points de vue, seulement Xaml ou de Comportements.
- Salut Kolky, je sais que cette réponse est probablement trop tard pour vous, près de 6 ans maintenant, mais il sera peut-être utile pour quelqu'un d'autre dans une situation similaire. Normalement, l'INTERFACE utilisateur logique de type de ce genre est acceptable en utilisant le pattern MVVM, telles que l'utilisation du code-behind de la classe. Voici un lien vers un article MSDN sur ça: msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx
Vous devez vous connecter pour publier un commentaire.
Je pense que Dave solution est bonne. Toutefois, une recommandation que je ferais est d'attraper le PreviewMouseWheel événement sur le scrollviewer au lieu de la grille de données. Si vous ne le faites pas, vous remarquerez peut-être quelques différences mineures, selon que vous utilisez le défilement sur la grille de données ou la barre de défilement lui-même. Le raisonnement est que le scrollviewer de gérer le défilement lorsque la souris les survole la barre de défilement, et la grille de données événement sera de gérer le défilement lorsque plus de la grille de données. Par exemple, une souris à molette de défilement sur la grille de données peut vous apporter en plus loin vers le bas de votre liste puis ce serait, en plus de la barre de défilement. Si vous le prenez sur le scrollviewer aperçu de l'événement, tous utilisent la même mesure en cas de défilement. Aussi, si vous le prenez de cette façon, vous n'aurez pas besoin de nom le scrollviewer élément, que vous n'aurez pas besoin d'une référence à l'objet dans la mesure où vous pouvez simplement taper fonte de l'expéditeur, de l'objet passé dans le scrollviewer PreviewMouseWheel événement. Enfin, je vous recommande le marquage de l'événement géré à la fin de l'événement, sauf si vous avez besoin de l'attraper dans un élément plus bas dans la hiérarchie pour une raison quelconque. L'exemple ci-dessous:
Je suis en supposant que la grille de données n'a pas besoin de défiler Ensemble de la VerticalScrollBar="None" dans la grille de données.
La grille de données avale le défilement de la souris de l'événement.
Ce que j'ai trouvé est d'utiliser le PreviewMouseWheel événement pour faire défiler le conteneur que vous souhaitez faire défiler. Vous devez nommer le scrollviewer pour modifier le décalage Vertical.
J'ai essayé N'B de la solution et il résout le problème avec le défilement sur une grille de données assez bien pour le cas où vous n'avez pas d'autres intérieure de défilement des contrôles.
Pour le cas où le défilement spectateur a que les enfants des autres défilement des contrôles et une grille de données, puis qui exige que l'événement ne devrait pas être marqué comme traité à la fin de la gestionnaire d'événement pour le principal de défilement de la visionneuse de sorte qu'il pourrait être atteint, également à l'intérieur de défilement témoins, mais qui a aussi pour effet que, lorsque le défilement doit se produire uniquement sur l'intérieur de défilement de contrôle, il sera également se produire sur le principal de défilement de l'afficheur.
J'ai donc mis à jour Dave solution avec la différence de défilement de la visionneuse est trouvé donc il ne sera pas nécessaire de connaître le nom de défilement de la visionneuse:
GetVisualParent
ne l'est pas.System.Windows.Media.VisualTreeHelper.GetParent(DependencyObject)
dansPresentationCore
Pour activer la prise en charge tactile vous pouvez aussi définir des
ScrollViewer.PanningMode
àNone
sur votreDataGrid
et de définir la même propriétéVerticalFirst
ou d'autres de la valeur de votre haut niveauScrollViewer
Exemple
Bien sûr utiliser le
PreviewMouseWheel
événement comme indiqué par N'B des réponses corriger l'original de la souris défilement question.Ou, vous pouvez simplement définir la Propriété Attachée à votre
ScrollViewer
Utilisation
Où b: est l'espace de noms qui contient ce comportement
De cette façon, votre pas de code-behind est nécessaire et que votre application est purement MVVM
Les gars j'ai vu la plupart de la solution posté par ici et, plus fondamentalement, ils sont tous de droite, mais je pense qu'il est plus facile et la plus élégante de la syntaxe que nous pourrions appliquer.
En supposant que nous n'avons pas besoin de faire défiler avec notre grille de données et plutôt nous voudrions faire défiler avec nos MainWindow
de la jachère "Dave" et "Vladim Tofan" réponse
Désolé, pour les mauvais en anglais.
@fjch1997, j'ai utilisé ta solution et ça marche plutôt bien.
Il n'y a qu'un seul problème que j'ai trouvé. Il est connecté avec le commentaire de @Vadim Tofan:
J'ai aussi essayé de supprimer
e.Handled = true
déclaration, mais l'effet n'est pas agréable - les deux rouleaux sont déplacés en même temps. Donc, finalement, j'ai amélioré un peu la méthode de gestionnaire d'événement à la suivante:Cela empêche maintenant à l'extérieur de la molette pour naviguer dans le cas où intérieure ScrollViewer existe.
J'ai trouvé que ScrollViewer ne peut pas être concaténés, ce qui signifie que si il est concaténé comme dans votre cas, la Grille commence sous le ScrollViewer tag et dans le réseau, nous avons DataGrid et dans le contrôle DataGrid à nouveau le ScrollViewer propriété a été définie. c'est à dire