Windows Presentation Foundation或WPF是用于在基于Windows的应用程序中呈现用户界面的子系统。
我有一个带有索引器属性的类,带有字符串键: 公共类 IndexerProvider { 公共对象 this[字符串键] { 得到 { 返回 ... } 放 ...
我试图将图像列表(列表)绑定到 StackPanel,我尝试使用 来分隔这些图像,但遗憾的是它不起作用。有人知道为什么吗? (我是 wpf 的菜鸟..s...
如何结合GridSplitter和DataGrid,其中DataGrid必须有垂直滚动条?
我有一个 xaml,或多或少看起来如下(我已经过滤了 Grid 和 RowDefinition 相关条目以显示 Grid、DataGrid 和 RowDefinition 条目: 我有一个 xaml,或多或少看起来如下(我过滤了 Grid 和 RowDefinition 相关条目以显示 Grid、DataGrid 和 RowDefinition 条目: <Grid x:Name="MainGrid"> <Grid.RowDefinitions> <RowDefinition Height="auto" MaxHeight="60"/> <RowDefinition /> </Grid.RowDefinitions> <Grid x:Name="Grd_Header" Grid.Row ="0" MaxHeight="60"> <Grid.RowDefinitions> <RowDefinition Height="0"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="10"></RowDefinition> </Grid.RowDefinitions> </Grid> <Grid x:Name="Grd_Data" Grid.Row="1"> <Grid.RowDefinitions> <RowDefinition Height="auto"></RowDefinition> <RowDefinition Height="10"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Grid x:Name="Grd_Act" Grid.Row="0" VerticalAlignment="Stretch"> <Grid.RowDefinitions> <RowDefinition Height="30"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <DataGrid Name="..." Grid.Row="1" Grid.Column="0"> <telerik:RadBusyIndicator Grid.Row="0" Grid.RowSpan="2" .../> </Grid> <GridSplitter Grid.Row="1" Height="3" Background="black" HorizontalAlignment="Stretch" /> <Grid x:Name="Grd_plan" Grid.Row="2"> <Grid.RowDefinitions> <RowDefinition Height="auto"></RowDefinition> <RowDefinition Height="*" MinHeight="50"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <TextBlock Text="planned..." Grid.Row="0" Grid.Column="0"/> <DataGrid Grid.Row="1" ...> <telerik:RadBusyIndicator Grid.RowSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BusyContent="Loading pallets" IsBusy="{Binding IsLoadingGepandeMatrijsPalletten}" Grid.ColumnSpan="2"/> </Grid> </Grid> </Grid> 乍一看,结果看起来或多或少还不错: 但是从我稍微移动 GridSplitter 的那一刻起,它就出现了部分错误:有一个滚动条(绿色),它必须保持存在。但是灰色空间(红色矩形中):它来自哪里? (在调试时,我了解到灰色区域属于一般视图或Grid,称为MainGrid。) 在我忘记之前:Grid.Resources包含不同的Style标签,就像DataGrid的这个标签: <Style TargetType="DataGrid"> <Setter Property="HorizontalAlignment" Value="Stretch"/> <Setter Property="VerticalAlignment" Value="Stretch"/> <Setter Property="AutoGenerateColumns" Value="False"/> <Setter Property="IsReadOnly" Value="True"/> <Setter Property="ColumnWidth" Value="Auto"/> <Setter Property="FontSize" Value="12"/> </Style> 我假设 Grid 元素 “Grd_Act” 和 “Grd_plan” 都在干扰布局。 它们的布局不正确,元素排列不整齐(冗余属性、错误值等)。 修复这些布局问题应该会恢复预期的调整大小行为(由 GridSplitter 触发)。 “Grd_Act” 这个Grid有一个非常奇怪的布局,其中为two元素定义了三行(为什么不是两行?)。 元素的排列也是错误的: RadBusyIndicator 放置在第一行并跨越两行。 DataGrid 放置在第二行,第二行也被跨越 RadBusyIndicator 占据 - 它们重叠。 最后一行是空的,但保留完整的空间/高度(星号大小)。这条线本质上导致了奇怪的调整大小行为。但这样的安排还是错误的。 只需将其设置为两行,每个元素一行: <Grid x:Name="Grd_Act" Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition Height="30" /> <!-- Busy indicator row --> <RowDefinition Height="*" /> <!-- DataGrid row --> </Grid.RowDefinitions> <telerik:RadBusyIndicator Grid.Row="0" .../> <DataGrid Name="..." Grid.Row="1" /> </Grid> “Grd_plan” 这个Grid正确定义了三行,每个元素一行。 但是,元素排列不正确: RadBusyIndicator 与 TextBlock 一起放置在第一行(重叠)。 RadBusyIndicator 的 Grid.RowSpan 属性设置为 2,这没有任何意义(拼写错误?)。相反,该元素必须放置在第三行。 没有定义列,但元素按列排列:TextBlock 显式放置在 0 列中,并且 RadBusyIndicator 跨越两列。您应该删除那些多余的 Grid.Column 和 Grid.ColumnSpan 值。 不要使用 GridRowSpan 除非你的元素按列排列或者你想创建覆盖(使用 z-index)。 <Grid x:Name="Grd_plan" Grid.Row="2"> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <!-- TextBlock row --> <RowDefinition Height="*" MinHeight="50" /> <!-- DataGrid row --> <RowDefinition Height="*" /> <!-- RadBusyIndicator row --> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="planned..." /> <DataGrid Grid.Row="1" ...> <telerik:RadBusyIndicator Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BusyContent="Loading pallets" IsBusy="{Binding IsLoadingGepandeMatrijsPalletten}" /> </Grid> 如果您想让繁忙指示器覆盖 DataGrid,只需将它们放在同一行并设置 Panel.ZIndex 属性来控制它们的渲染顺序(z-index)。不需要(或合理)行跨度。
我通过将 WPF 控件放在网格上然后将其保存到文件来创建图像。我从不展示网格。效果很好。 但是当我尝试将其放入任务和 Task.Run 中时,它失败并显示: ...
我有一个使用 MVVM 模式的 WPF 应用程序,当它忙于执行用户必须等待的操作时,有时必须显示等待光标。感谢本页上的答案组合:d...
所以我的 MainWindow.xaml 上有一个文本框。 所以我的 MainWindow.xaml 上有一个文本框。 <Window x:Class="HelloICommand.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ... <Grid> <TextBox HorizontalAlignment="Left" Height="23" Margin="337,195,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"> <TextBox.InputBindings> <KeyBinding Command="{Binding }" Key="Enter"></KeyBinding> </TextBox.InputBindings> </TextBox> </Grid> </Window> 正如您所看到的,我想将我的 Enter 键绑定到可以单击 Enter 的位置,它会显示一个消息框,其中包含文本框中的文本。 在我的 MainWindow.cs 中,我像这样设置数据上下文。 public MainWindow() { InitializeComponent(); DataContext = new ServerViewModel(); } 然后我就有了实际的 ServerViewModel 以及其中的其他所有内容 这就是我遇到问题的地方,如何将文本从 TextBox 传递到该方法,以便每次单击 Enter 时都可以看到消息。 class ServerViewModel { private TextBoxCommand textCommand { get; private set; } public ServerViewModel() { textCommand = new TextBoxCommand(SendMessage); } //How do I pass the text from the textbox as a parameter here? public void SendMessage() { MessageBox.Show(""); } } I命令接口 class TextBoxCommand : ICommand { public Action _sendMethod; public TextBoxCommand(Action SendMethod) { _sendMethod = SendMethod; } public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { } public event EventHandler CanExecuteChanged; } 视图只能绑定到公共属性的命令。这意味着第一步是将您的命令定义为公共(只读)属性: public TextBoxCommand TextCommand { get; } ICommand 接口允许将对象作为参数传递给其执行函数。如果您的命令实现,TextBoxCommand允许传递此参数,只需将该参数添加到您的方法中,将其转换为字符串,然后显示您的消息: private void SendMessage(object parameter) { MessageBox.Show((string)parameter); } 如果您的 TextBoxCommand 不允许传递参数,则像如何实现可重用 ICommand 所示的简单实现即可解决问题。只需将您的 TextBoxCommand 替换为教程中的 DelegateCommand 即可。 要从您的视图中正确执行命令,您现在需要将命令绑定到 TextCommand 属性。第二步是将文本框的文本设置为命令参数。使用此名称,您可以绑定到 Text 属性并将其作为参数传递给您的命令。因此,您需要为文本框命名。这是最小的例子: <TextBox x:Name="yourTextBox> <TextBox.InputBindings> <KeyBinding Key="Enter" Command="{Binding TextCommand}" CommandParameter="{Binding Text, ElementName=yourTextBox}"/> </TextBox.InputBindings> </TextBox>
我可以在 WPF 项目中控制 Windows 设置焦点辅助(开/关)吗
我想在我的 C# WPF 项目中实现一项功能,在应用程序中,用户可以使用一个复选框来打开/关闭焦点辅助(Windows 10 中的设置),该复选框会自动切换...
我正在构建一个 C# WPF 应用程序,并且希望能够以编程方式启用和禁用 Windows 系统功能焦点辅助。 我尝试研究如何控制此功能
我有一个 DataGrid,其中包含 XAML 列,如下所示: 我有一个 DataGrid,其中包含 XAML 列: <DataGridTextColumn Header="Time" Binding="{Binding Date, StringFormat='yyyy-MM-dd HH:mm:ss'}" SortMemberPath="Date" SortDirection="Descending" Width="130" CanUserResize="True" /> <DataGridTextColumn Header="Level" Binding="{Binding Level}" Width="60" CanUserResize="True" /> <DataGridTextColumn Header="Source" Binding="{Binding Logger}" Width="150" CanUserResize="True" /> <DataGridTextColumn Header="Message" Binding="{Binding Message}" Width="*" CanUserResize="True" /> 我将其绑定到 ObservableCollection<EalsLogEvent>,其中输入 EalsLogEvent.Date DateTime: public ObservableCollection<EalsLogEvent> LogEvents { get { return _logEvents; } } 网格视图模型使用计时器来刷新自身,网格的一切看起来都很好,除了在应用程序启动时首次加载时。然后,Time 列似乎按降序排序,但实际上是按升序排序。 为了正确排序,我必须单击列标题两次;第一次将顺序更改为升序,现在与列的内容匹配。第二次单击列标题会将其排序顺序更改回降序,这次它对列内容进行正确排序,即降序。 如果我在 _logEvents 刷新时使用 LINQ 对集合进行排序,我会丢失用户通过单击列标题为该列设置的任何顺序。如果我必须让视图告诉模型 LINQ 排序应该使用哪个顺序,那就有点糟糕了。 您可以在 XAML 中使用 CollectionViewSource 来定义默认排序。 假设我们有一个视图模型: public class ViewModel : INotifyPropertyChanged { public ObservableCollection<Item> Items { get; private set; } } 我们可以为 CollectionView 集合创建自定义 Items: <Window xmlns:l="clr-namespace:YourNamespace" xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"> <Window.DataContext> <l:ViewModel/> </Window.DataContext> <Window.Resources> <CollectionViewSource Source="{Binding Items}" x:Key="GridItems"> <CollectionViewSource.SortDescriptions> <scm:SortDescription PropertyName="Date" Direction="Descending"/> </CollectionViewSource.SortDescriptions> </CollectionViewSource> </Window.Resources> <DataGrid ItemsSource="{Binding Source={StaticResource GridItems}}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Time" Binding="{Binding Date, StringFormat='yyyy-MM-dd HH:mm:ss'}" Width="130" CanUserResize="True" /> <DataGridTextColumn Header="Level" Binding="{Binding Level}" Width="60" CanUserResize="True" /> <DataGridTextColumn Header="Source" Binding="{Binding Logger}" Width="150" CanUserResize="True" /> <DataGridTextColumn Header="Message" Binding="{Binding Message}" Width="*" CanUserResize="True" /> </DataGrid.Columns> </DataGrid> </Window> 使用这种方法,您的底层源集合(本例中为Items)将不会受到影响,排序仅发生在视图中。 正如您可以在 MSDN 中阅读的那样: 您可以将集合视图视为绑定顶部的层 源集合,允许您导航和显示 基于排序、过滤和分组查询的集合,全部无需 必须操纵底层源集合本身。如果 源集合实现了 INotifyCollectionChanged 接口, CollectionChanged 事件引发的更改将传播到 意见。 您还应该注意以下事项: 所有集合都有一个默认的 CollectionView。 WPF 始终绑定到 视图而不是集合。如果直接绑定到集合, WPF 实际上绑定到该集合的默认视图。 因此,使用 CollectionViewSource,您只需为您的集合定义一个自定义视图。 您应该在视图模型中创建 2 个属性: private ObservableCollection<EalsLogEvent> logEvents = new ObservableCollection<EalsLogEvent>(); private ICollectionView logEventsView; public ObservableCollection<EalsLogEvent> LogEvents { get { return this.logEvents; } set { this.SetProperty(ref this.logEvents, value); } } public ICollectionView LogEventsView { get { if (this.logEventsView == null) { this.logEventsView= CollectionViewSource.GetDefaultView(this.LogEvents); this.logEventsView.SortDescriptions.Add(new SortDescription("Time", ListSortDirection.Descending)); } return this.logEventsView; } } 将 DataGrid 绑定到 LogEventsView,并使用 LogEvents 添加或删除项目。 这允许默认排序和用户排序。
这是我的 ListView 和文本框的设置,用于将选择的项目显示为字符串。 这是我的 ListView 和文本框的设置,用于显示作为字符串选择的项目。 <ListView Name="myListView" SelectionChanged="myListBox_SelectionChanged_1" SelectionMode="Multiple"> <ListViewItem Content="Item 1"/> <ListViewItem Content="Item 2"/> <ListViewItem Content="Item 3"/> </ListView> <TextBox Name="tb" Width="140" Height="30" Margin="20"/> 这是成功输出ListViewItem的值的行。 string output = ((ListBoxItem)myListView.SelectedItem).Content.ToString(); /// output: Item 1 但是我不知道如何在foreach循环中实现它 foreach (ListBoxItem item in myListView.SelectedItems) { string output = item.ToString(); tb.AppendText(output); } foreach 循环当前输出: System.Windows.Controls.ListViewItem: {the ListViewItem value} 我想去掉前面的“System.Windows...”。 我尝试将此行放在 foreach 循环中,但它只输出选定的第一个 ListViewItem 的值。 string output = ((ListBoxItem)myListView.SelectedItem).Content.ToString(); 预期输出应为文本框中的“Item 1 Item 2...”。 当 object.ToString 未被覆盖时,它返回 object.GetType().ToString(),这使得 object.ToString 返回类型的完全限定名称。 要删除命名空间,您可以引用 Type.Name 属性。 然后,为了提高 UI 的性能,请勿通过连接其值来重复更新 TextBox。这根本没有效率。 相反,使用 StringBuilder 构建文本值并更新 TextBox 一次: var textBoxValueBuilder = new SringBuilder(); foreach (ListBoxItem item in myListView.SelectedItems) { string output = item.GetType().Name; textBoxValueBuilder.Append(output); } tb.Text = textBoxValueBuilder.ToString();
我需要让 DataGrid 高度自动扩展以满足其所在选项卡页的高度。目前,DataGrid 的高度仅扩展以满足其包含数据的所有行的高度。 这是一个
我正在研究 bingmap wpf。我在鼠标的单击事件上创建了图钉。现在我需要使其可拖动并根据图钉位置跟踪坐标。任何人都知道如何...
如何将 Control 的内容属性作为 CommandParameter WPF 传递
我有一个 WPF 项目,有 19 个单选按钮。我想设置每个命令属性。 为了分隔所有命令操作,我想将 RadioButton Content 属性作为 CommandParameter 发送。 我尝试
如何让我的 ScrollViewer Vertical ScrollBar 始终可见?
我有一个 ScrollViewer 的样式,我希望即使没有可滚动的内容,垂直滚动条也可见,但我似乎无法让它工作。根据我在之前的问题中发现的内容...
我目前正在学习 WPF 动画。 目前我有这个按钮样式: <Setter Property="FontFamily" Value="{DynamicResource </desc> <question vote="0"> <p>我目前正在学习 WPF 动画。</p> <p>目前我有这个按钮样式:</p> <pre><code><Style TargetType="Button"> <Setter Property="FontFamily" Value="{DynamicResource DefaultFont}" /> <Setter Property="MinHeight" Value="{DynamicResource MinHeight}" /> <Setter Property="Background" Value="{DynamicResource C4}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid SnapsToDevicePixels="True"> <Border x:Name="Border" BorderThickness="0" CornerRadius="{DynamicResource Radius}" BorderBrush="{TemplateBinding BorderBrush}"> <Border.Background> <SolidColorBrush x:Name="borderBackground" Color="{StaticResource Col5}" /> </Border.Background> <ContentPresenter x:Name="Content" VerticalAlignment="Center" HorizontalAlignment="Center" RecognizesAccessKey="True" /> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderBrush" TargetName="Border" Value="Black" /> <Trigger.EnterActions> <BeginStoryboard x:Name="beginStoryboard"> <Storyboard> <ColorAnimation Storyboard.TargetName="borderBackground" Storyboard.TargetProperty="Color" To="{StaticResource Col2}" Duration="0:0:0.2"> </ColorAnimation> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> <Trigger.ExitActions> <RemoveStoryboard BeginStoryboardName="beginStoryboard" /> <BeginStoryboard x:Name="e"> <Storyboard> <ColorAnimation Storyboard.TargetName="borderBackground" Storyboard.TargetProperty="Color" To="{StaticResource Col5}" Duration="0:0:0.2"> </ColorAnimation> </Storyboard> </BeginStoryboard> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> <Style.Resources> <Style TargetType="Border"> <Setter Property="CornerRadius" Value="{DynamicResource Radius}" /> </Style> </Style.Resources> </Style> </code></pre> <p>如您所见,这种风格应该做一些事情:</p> <ul> <li>应用默认值 <pre><code>FontFamily</code></pre>、<pre><code>MinHeight</code></pre> 和 <pre><code>Background</code></pre>;</li> <li>使用 <pre><code>ColorAnimation</code></pre> 动画鼠标进入和鼠标离开效果。颜色被定义为具有 Col1、Col2 等名称的资源。</li> </ul> <p>一切正常(即使我怀疑这种风格可以用更简洁的方式重写,但我需要指出正确的方向)。</p> <p>我的问题是:我需要基于这个主样式创建另一个样式,所以我写了类似的内容:</p> <pre><code><Style TargetType="Button" x:Key="AccentOnMouseOver" BasedOn="{StaticResource {x:Type Button}}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderBrush" Value="DarkGreen"/> <Setter Property="BorderThickness" Value="1" /> </Trigger> </Style.Triggers> </Style> </code></pre> <p>不幸的是,这不起作用(应用了基本样式,但没有 <pre><code>BorderBrush</code></pre> 颜色)。 如何使用背景<pre><code>ColorAnimation</code></pre>编写基本样式,然后使用另一种样式派生,添加其他<pre><code>Triggers</code></pre>?</p> <p>解决方案是复制并粘贴整个基本样式,添加 x:Key 并编辑我需要的属性,但我想要更干净的东西(这样,如果我更改动画部分,它将应用于所有派生样式) .</p> <p>非常感谢任何帮助。</p> </question> <answer tick="false" vote="0"> <p>主要错误是对元素模板的逻辑及其与样式的交互的错误理解。</p> <ol> <li><p>在您的示例中,主边框显示边框,但它有一个“硬”指定值:<pre><code><Border x:Name="Border" BorderThickness="0"</code></pre>。至少,您需要将其更改为 <pre><code><Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}"</code></pre>。</p> </li> <li><p>“MouseOver”状态的边框颜色在模板触发器中设置:</p> </li> </ol> <pre><code> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderBrush" TargetName="Border" Value="Black" /> </code></pre> <p>因此,在这种状态下,对父元素属性的绑定将不再起作用(其优先级低于模板触发setter):<pre><code><Border x:Name="Border" ... BorderBrush="{TemplateBinding BorderBrush}"></code></pre>。因此,对于这种状态,为父元素的属性设置值是没有意义的。</p> <p>您不能同时为一个属性设置多个值。因此,如果您稍后需要在使用元素的位置触发同一属性的更改,您应该想出某种机制来禁用模板中的触发器。</p> </answer> </body></html>
如果我取出启用 wpf 实时图表的代码,那么我的数据绑定代码可以正常工作,但是当显示图表时,到我的标签的数据绑定不再显示数据字符串。 我用的是
在WPF中禁用硬件加速的步骤是什么?究竟是什么?它是 Windows 设置、Visual Studio 设置还是您在 WPF 项目代码中更改的内容?会吗
我有一个绑定可观察集合的数据网格。当我单击添加新按钮时,我会将新行添加到集合中。我如何实用地滚动到新行。 数据网格 XMAL 我有一个绑定可观察集合的数据网格。当我单击添加新按钮时,我会将新行添加到集合中。我如何实用地滚动到新行。 数据网格XMAL <DataGrid SelectedIndex="{Binding SelectedIntex}" IsEnabled="{Binding IsKeySet}" CanUserDeleteRows="False" CanUserAddRows="False" Name="dgwTemplateDetails" SelectionMode="Single" ItemsSource="{Binding OrderTemplateList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedOrderTemplate}" IsReadOnly="False" AutoGenerateColumns="False" Width="auto"> <DataGrid.Columns> <DataGridTextColumn Header="Srl No" Visibility="Hidden" Binding="{Binding SrlNo}"/> <DataGridTextColumn Header="Act Code" Width="75" Binding="{Binding ActCode, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="Act Name" Width="275" Binding="{Binding ActName, UpdateSourceTrigger=PropertyChanged}"/> <DataGridTextColumn Header="No. Of Days" Width="75" Binding="{Binding NoOfDays, UpdateSourceTrigger=PropertyChanged}"/> <DataGridCheckBoxColumn Header="Is Cutting" Width="75" Binding="{Binding IsCutSelected, UpdateSourceTrigger=PropertyChanged}" /> </DataGrid.Columns> </DataGrid> VM 添加行功能 if (ValidateHeader()) { if (OrderTemplateList == null) this.OrderTemplateList = new ObservableCollection<EventManagementTemplate>(); EventManagementTemplate obJEvent = new EventManagementTemplate(); obJEvent.BuyerCode = this.BuyerCode; this.OrderTemplateList.Add(obJEvent); int no = 1; this.OrderTemplateList.ToList().ForEach(m => m.SrlNo = no++); } 您需要执行以下操作: 为您的 dataGrid 命名,以便您可以在代码隐藏文件(与包含数据网格的 xaml 文件配对的 .cs 文件)中访问它 向您的视图模型添加一个委托,以供 AddRow 函数调用 - 该委托应将您想要滚动到视图中的对象作为参数。 让包含数据网格的背后代码订阅委托==>基本上,背后的代码是提供对视图模型的回调。回调后面的代码将是滚动到新项目的代码。 回调应调用数据网格的 ScrollIntoView 函数 (http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.scrollintoview(v=vs.110).aspx) 在视图模型的添加行函数结束时(添加项目后),使用要滚动到视图中的项目调用委托。 示例代码: public class MyViewModel { // declare the delegate signature... delegate void ScrollIntoViewDelegateSignature(EventManagementTemplate objEvent); // create a pointer to the delegate that can be set by the code behind... public ScrollIntoViewDelegateSignature ScrollIntoView {get; set;} protected AddRow() { .. your code here // call the delegate... if (ScrollIntoView != null) ScrollIntoView(objEvent) } } public class MyControlOrWindowThatContainsDataGrid : UserControl/ChildWindow/Page { public void Initialize() { ...your code here // set the scrollIntoView delegate... myViewModel.ScrollIntoView = ScrollIntoView; } // create a ScrollIntoView function // ==> the return value and parameters MUST match the delegate signature public void ScrollIntoView(EventManagementTemplate objEvent) { myDataGrid.ScrollIntoView(objEvent); } } 参考 http://msdn.microsoft.com/en-us/library/900fyy8e.aspx 我认为最好使用事件来做到这一点,但这更复杂。 以下是有关如何使用事件的 msdn 文档:http://msdn.microsoft.com/en-us/library/awbftdfh.aspx 您可以为 DataGrid 创建行为。在此代码中,仅当新行添加到集合中时,它才会滚动到网格的最后一行。您可以根据任何条件修改它。有时需要添加一些延迟。如果不需要,您可以排除。 public class AutoScrollToEndBehavior : Behavior<DataGrid> { private DateTime _lastCollectionChangedTime = DateTime.MinValue; protected override void OnAttached() { base.OnAttached(); SubscribeToCollectionChanged(); } protected override void OnDetaching() { base.OnDetaching(); UnsubscribeFromCollectionChanged(); } private void SubscribeToCollectionChanged() { if (AssociatedObject.Items is ICollectionView collectionView) { collectionView.CollectionChanged += OnCollectionChanged; } } private void UnsubscribeFromCollectionChanged() { if (AssociatedObject.Items is ICollectionView collectionView) { collectionView.CollectionChanged -= OnCollectionChanged; } } private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { _lastCollectionChangedTime = DateTime.Now; Task.Delay(100).ContinueWith(_ => { if ((DateTime.Now - _lastCollectionChangedTime).TotalMilliseconds > 100) { ScrollToEnd(); } }, TaskScheduler.FromCurrentSynchronizationContext()); } } private void ScrollToEnd() { if (AssociatedObject.Items.Count > 0) { var lastItem = AssociatedObject.Items[AssociatedObject.Items.Count - 1]; AssociatedObject.Dispatcher.Invoke(() => { AssociatedObject.ScrollIntoView(lastItem); }); } } } 在 XAML 中, 在 datagrid () 的结束标记上方添加以下代码 <b:Interaction.Behaviors> <behavior:AutoScrollToEndBehavior/> </b:Interaction.Behaviors> </DataGrid> 在 DataGrid 中添加项目后尝试此操作: dgwTemplateDetails.ScrollIntoView(obJEvent); 此行将滚动到当前添加的元素。
如何在 Visual Studio 2019 中引用程序集? .NET Core 上的 WPF
我正在尝试使用FolderBrowserDialog 创建WPF 应用程序,并且我知道我需要添加对System.Windows.Forms 的引用。唯一的问题是,没有任何来源可以告诉您如何...
c# 蓝牙 LE - 写入配置错误 - ValueChanged 从未被调用
所以我尝试将我的 C# WPF 程序连接到 BLE 设备,这是连接到设备的代码: 私有异步任务 ConnectToWatcher(DeviceInformation deviceInfo) { 尝试 { /...