我有一個用物件填充的資料網格。假設客戶和每個客戶持有一個專案。我有一個按鈕,可以將客戶添加到帶有隨機專案的資料網格中。如果我不斷將客戶添加到資料網格中,直到客戶數量超過資料網格的高度(這會導致出現滾動),那么超出該點的資料在我按下它之前是不準確的(重繪 它? )。我通過使我的資料網格高度更大來測驗這一點,一旦我開始插入沒有出現在我的視圖中的行(直到我向下滾動),資料似乎沒有正確同步。我懷疑這是一個同步/初始化問題。
我的資料網格 xaml:
<DataGrid x:Name="DG" HorizontalAlignment="Left" Height="291" Margin="706,84,0,0" VerticalAlignment="Top" Width="300"
ItemsSource="{Binding CustomersList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Customer" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
<DataGridTemplateColumn Header="Item" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<local:CustomComboBox SelectedItem="{Binding Item, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding DataContext.ItemsList, ElementName=MainWind}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
自定義組合框
<Grid DataContext="{Binding ElementName=Root}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- Image at the side of the ComboBox -->
<Image Height="30" Width="30" Grid.Column="0"
Source="{Binding SelectedItem.Type, Converter={StaticResource ImageConverter}}"/>
<!-- Actual ComboBox -->
<ComboBox x:Name="CustomCombo" Grid.Column="1"
IsTextSearchEnabled="False" IsReadOnly="True" KeyDown="CustomCombo_KeyDown"
DropDownOpened="CustomCombo_DropDownOpened" DropDownClosed="CustomCombo_DropDownClosed"
Loaded="CustomCombo_Loaded"
IsEditable="True" TextSearch.TextPath="Name"
Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding ItemsSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!-- StackPanel consisting of an Image and TextBlock as ItemTemplate-->
<Image Height="30" Width="30"
Source="{Binding Path=Type, Converter={StaticResource ImageConverter}}"/>
<TextBlock Text="{Binding Path=Name}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
我不知道這個問題的技術術語來尋找解決方案。
uj5u.com熱心網友回復:
干得好。github.com/melsawy93/WPFTestAppBug
這個存盤庫有很多問題。
首先,存盤庫本身創建不正確。它應該包含忽略和屬性檔案。由于它們的缺席,很多額外的檔案進入了存盤庫,包括 .vs、bin、obj 檔案夾。他們的存在在每次提交時增加了很多想象中的變化。
嘗試通過 Git Visul Studio 選單創建一個新的空存盤庫。您將在那里看到忽略和屬性檔案。將它們復制到您的存盤庫。并使用 CitHub Web 界面洗掉其中多余的檔案夾。
我將在這里發布需要對源代碼進行的更改:
主視窗。
<Window x:Class="WPFTestApp.MainWindow"
------------------
------------------
DataContext="{DynamicResource vm}">
<FrameworkElement.Resources>
<vm:MainViewModel x:Key="vm"/>
</FrameworkElement.Resources>
<syncfusion:GridTemplateColumn.CellTemplate>
<DataTemplate>
<local:CustomComboBox SelectedItem="{Binding FruitorVegie}"
ItemsSource="{Binding ItemsList, Source={StaticResource vm}}"/>
</DataTemplate>
</syncfusion:GridTemplateColumn.CellTemplate>
private MainViewModel _vm;
public MainWindow()
{
SelectedFruitsOrVegie = new ObservableCollection<IsFruitOrVegetable>();
InitializeComponent();
_vm = (MainViewModel)DataContext;
}
自定義組合框
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace WPFTestApp
{
/// <summary>
/// Interaction logic for CustomComboBox.xaml
/// </summary>
///
public partial class CustomComboBox : CustomComboBoxBase
{
public CustomComboBox()
{
InitializeComponent();
}
}
public partial class CustomComboBoxBase : UserControl
{
#region States
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource",
typeof(IEnumerable<IsFruitOrVegetable>),
typeof(CustomComboBoxBase),
new PropertyMetadata(null)
);
//private IsFruitOrVegetable[] defaultList = null;
public IEnumerable<IsFruitOrVegetable> ItemsSource
{
get
{
return (IEnumerable<IsFruitOrVegetable>)GetValue(ItemsSourceProperty);
}
set => SetValue(ItemsSourceProperty, value);
}
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
"SelectedItem",
typeof(IsFruitOrVegetable),
typeof(CustomComboBoxBase),
new FrameworkPropertyMetadata(null, (d, e) => ((CustomComboBoxBase)d).OnSelectedItemChanged(e)) { BindsTwoWayByDefault = true }
);
private void OnSelectedItemChanged(object e)
{
Text = SelectedItem?.Name;
}
public IsFruitOrVegetable SelectedItem
{
get
{
return (IsFruitOrVegetable)GetValue(SelectedItemProperty);
}
set
{
SetValue(SelectedItemProperty, value);
}
}
/// <summary>
/// Element name or filter text for the <see cref="ItemsSource"/> collection.
/// </summary>
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
/// <summary><see cref="DependencyProperty"/> for property <see cref="Text"/>.</summary>
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(
nameof(Text),
typeof(string),
typeof(CustomComboBoxBase),
new FrameworkPropertyMetadata(null, (d, e) => ((CustomComboBoxBase)d).OnTextChanged((string)e.NewValue)) { BindsTwoWayByDefault = true });
private void OnTextChanged(string filterText)
{
if (itemsSourceViewSource.View is null)
return;
filterText = filterText?.Trim();
if (string.IsNullOrEmpty(filterText))
{
itemsSourceViewSource.View.Filter = null;
}
else
{
itemsSourceViewSource.View.Filter = item => ((IsFruitOrVegetable)(item)).Name.IndexOf(filterText, StringComparison.OrdinalIgnoreCase) > -1;
}
}
public CustomComboBoxBase()
{
DependencyPropertyDescriptor.FromProperty(CollectionViewSource.SourceProperty, typeof(CollectionViewSource))
.AddValueChanged(itemsSourceViewSource, OnItemsSourceViewChanged);
BindingOperations.SetBinding(
itemsSourceViewSource,
CollectionViewSource.SourceProperty,
new Binding() { Path = new PropertyPath(ItemsSourceProperty), Source = this });
}
private void OnItemsSourceViewChanged(object sender, EventArgs e)
{
FilteredItemsSource = itemsSourceViewSource.View;
OnTextChanged(Text);
}
/// <summary>
/// The source for the filtered view of the ItemsSource collection.
/// </summary>
private CollectionViewSource itemsSourceViewSource = new CollectionViewSource();
/// <summary>
/// A filtered view of the ItemsSource collection.
/// </summary>
public ICollectionView FilteredItemsSource
{
get => (ICollectionView)GetValue(FilteredItemsSourceProperty);
private set => SetValue(FilteredItemsSourcePropertyKey, value);
}
private static readonly DependencyPropertyKey FilteredItemsSourcePropertyKey =
DependencyProperty.RegisterReadOnly(nameof(FilteredItemsSource), typeof(ICollectionView), typeof(CustomComboBoxBase), new PropertyMetadata(null));
/// <summary><see cref="DependencyProperty"/> for property <see cref="FilteredItemsSource"/>.</summary>
public static readonly DependencyProperty FilteredItemsSourceProperty = FilteredItemsSourcePropertyKey.DependencyProperty;
#endregion
#region Event Handlers
private IsFruitOrVegetable lastSelectedItem;
// Saves Last Selected Item when the drop down is opened
protected void CustomCombo_DropDownOpened(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
comboBox.IsReadOnly = false;
if (SelectedItem != null && SelectedItem.Type != FoodType.None)
{
lastSelectedItem = SelectedItem;
}
Text = "";
}
// Validates if Selected Item is of Type None, then it will revert back to
// the last selected Item which is saved
protected void CustomCombo_DropDownClosed(object sender, EventArgs e)
{
ComboBox comboBox = sender as ComboBox;
comboBox.IsReadOnly = true;
if (SelectedItem == null || SelectedItem.Type == FoodType.None)
{
if (lastSelectedItem != null)
{
SelectedItem = lastSelectedItem;
Text = SelectedItem.Name;
}
else
{
SelectedItem = null;
Text = "";
}
}
else if (SelectedItem != null && SelectedItem.Type != FoodType.None)
{
Text = SelectedItem.Name;
}
}
#endregion
protected void CustomCombo_KeyDown(object sender, KeyEventArgs e)
{
ComboBox comboBox = sender as ComboBox;
if (!comboBox.IsDropDownOpen && !(e.Key == Key.Enter || e.Key == Key.Escape))
{
comboBox.IsDropDownOpen = true;
}
}
}
}
<local:CustomComboBoxBase x:Class="WPFTestApp.CustomComboBox"
x:Name="Root"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFTestApp"
xmlns:cnvrt="clr-namespace:WPFTestApp.Converter"
xmlns:vm="clr-namespace:WPFTestApp.ViewModel"
mc:Ignorable="d"
d:DesignHeight="30" d:DesignWidth="150">
<FrameworkElement.Resources>
<cnvrt:ImageConverter x:Key="ImageConverter"/>
</FrameworkElement.Resources>
<Grid DataContext="{Binding ElementName=Root}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- Image at the side of the ComboBox -->
<Image Height="30" Width="30" Grid.Column="0"
Source="{Binding SelectedItem.Type, Converter={StaticResource ImageConverter}}"/>
<!-- Actual ComboBox -->
<ComboBox x:Name="CustomCombo" Grid.Column="1"
IsTextSearchEnabled="False" IsReadOnly="True" KeyDown="CustomCombo_KeyDown"
DropDownOpened="CustomCombo_DropDownOpened" DropDownClosed="CustomCombo_DropDownClosed"
IsEditable="True" TextSearch.TextPath="Name"
Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding FilteredItemsSource}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!-- StackPanel consisting of an Image and TextBlock as ItemTemplate-->
<Image Height="30" Width="30"
Source="{Binding Path=Type, Converter={StaticResource ImageConverter}}"/>
<TextBlock Text="{Binding Path=Name}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</local:CustomComboBoxBase>
PS請記住,我沒有修復所有錯誤。僅更改了對解決本主題頂部的問題重要的內容。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/527046.html
標籤:C#wpf数据网格初始化
