我在兩個不同的 tabitems 中有兩個資料網格。第一個 tabitem 中的資料網格顯示了一些關于應用程式加載的特定資料,如果資料發生變化,應該會更新,非常簡單。第二個 tabitem 的 datagrid 在應用程式加載時應該是空的,但是當從組合框中選擇/鍵入一個專案時,它應該根據該組合框所選專案過濾資料并顯示在第二個 tabitem 的 datagrid 上的過濾資料上(維護 MVVM 模式)。
這是我嘗試過的:
XAML
<TabControl>
<TabItem Header="Pending Bills">
<DataGrid ItemsSource="{Binding FilteredBills}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn
Header="Vendor"
Binding="{Binding Path=Party, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
<DataGridTextColumn
Header="Bill No."
Binding="{Binding Path=BillNo, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
......
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Header="Filtered Bills">
........
<DataGrid Grid.Row="0" ItemsSource="{Binding AllBills}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn
Header="Vendor"
Binding="{Binding Path=Party, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
<DataGridTextColumn
Header="Bill No."
Binding="{Binding Path=BillNo, Mode=OneWay}"
Width="275"
IsReadOnly="True" />
......
</DataGrid.Columns>
</DataGrid>
<StackPanel Orientation="Horizontal">
<ComboBox x:Name="cmbBox" ItemsSource="{Binding ComboItems}" SelectedItem="{Binding SelectedCBItem}"/>
</StackPanel>
</Grid>
</TabItem>
</TabControl>
一個基礎視圖模型,以啟用PropertyChangedEventHandler
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
基本型號:
public class Bills : ViewModelBase
{
private int _id;
public int Id
{
get
{
return _id;
}
set
{
_id = value;
OnPropertyChanged("Id");
}
}
private string _party;
public string Party
{
get
{
return _party;
}
set
{
_party = value;
OnPropertyChanged("Party");
}
}
private string _billNo;
public string BillNo
{
get
{
return _billNo;
}
set
{
_billNo = value;
OnPropertyChanged("BillNo");
}
}
.......
}
billsviewmodel 和一個名為 Model 的輔助資料訪問類:
public class BillsViewModel : ViewModelBase
{
public BillsViewModel()
{
cvsAll.Source = m.AllBills;
cvsFiltered.Source = m.FilteredBills;
}
Model m = new Model();
CollectionViewSource cvsAll = new CollectionViewSource();
public ICollectionView AllBills
{
get { return cvsAll.View; }
}
public List<string> ComboItems
{
get { return m.UniqueValues(); }
}
CollectionViewSource cvsFiltered = new CollectionViewSource();
public ICollectionView FilteredBills
{
get { return cvsFiltered.View; }
}
private string _selectedCBItem;
public string SelectedCBItem
{
get { return _selectedCBItem; }
set
{
_selectedCBItem = value;
cvsFiltered.Source = m.GetBills_Pen(value);
OnPropertyChanged("SelectedCBItem");
}
}
}
public class Model
{
private List<Bills> _allBills;
public List<Bills> AllBills
{
get
{
if (_allBills == null) LoadAllBillsFromDatabase();
return _allBills;
}
}
private List<Bills> _filteredBills;
public List<Bills> FilteredBills
{
get
{
if (_filteredBills == null) LoadUnpaidBillsFromDatabase();
return _filteredBills;
}
}
public void LoadAllBillsFromDatabase()
{
SQLiteConnection m_dbConnection = new SQLiteConnection(@"Data Source=Bills.db;");
SQLiteCommand sqlCom = new SQLiteCommand(@"Select * From billdata", m_dbConnection);
SQLiteDataAdapter sda = new SQLiteDataAdapter(sqlCom);
DataTable dt = new DataTable();
sda.Fill(dt);
_allBills = new List<Bills>();
foreach (DataRow row in dt.Rows)
{
_allBills.Add(new Bills()
{
Id = Convert.ToInt32(row["Id"]),
Party = (string)row["Party"],
BillNo = (string)row["BillNo"],
.......
});
}
m_dbConnection.Close();
}
public void LoadUnpaidBillsFromDatabase()
{
SQLiteConnection m_dbConnection = new SQLiteConnection(@"Data Source=Bills.db;");
SQLiteCommand sqlCom = new SQLiteCommand(@"Select * From billdata where PaidOn != ''", m_dbConnection);
SQLiteDataAdapter sda = new SQLiteDataAdapter(sqlCom);
DataTable dt = new DataTable();
sda.Fill(dt);
_filteredBills = new List<Bills>();
foreach (DataRow row in dt.Rows)
{
_filteredBills.Add(new Bills()
{
Id = Convert.ToInt32(row["Id"]),
Party = (string)row["Party"],
BillNo = (string)row["BillNo"],
.......
});
}
m_dbConnection.Close();
}
public List<string> UniqueValues()
{
return _allBills.Select((s) => s.Party).Distinct().OrderBy((s) => s).ToList();
}
public List<Bills> GetBills_Pen(string filterValue)
{
return _allBills.FindAll(s => s.Party == filterValue).ToList();
}
}
有2個問題:
- 第二個 tabitem 上的資料網格正在顯示應用程式加載的所有資料
- 當我在組合框中選擇或鍵入有效專案時,第二個 tabitem 上的資料網格未顯示過濾后的資料。
我沒有ICollectionView
以正確的方式實施或者我在這里做錯了什么,最重要的是我該如何解決這個問題?
uj5u.com熱心網友回復:
這應該有效。我還向 ViewModelBase 添加了一個函式以使代碼更短
public class ViewModelBase
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void SetValue<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
field = value;
OnPropertyChanged(propertyName);
}
}
public class BillsViewModel : ViewModelBase
{
private List<BillViewModel> _allBills;
public BillsViewModel()
{
_allBills = m.AllBills;
AllBills = new ListCollectionView(_allBills);
ComboItems = _allBills.Select(b => b.Party).Distinct().OrderBy(b => b).ToList();
FilteredBills = new ListCollectionView(_allBills)
{
Filter = o => ((BillViewModel)o).Party == SelectedCBItem
};
}
Model m = new Model();
public ICollectionView AllBills { get; private set; }
public ICollectionView FilteredBills { get; private set; }
public List<string> ComboItems { get; private set; }
private string _selectedCBItem;
public string SelectedCBItem
{
get { return _selectedCBItem; }
set
{
SetValue(ref _selectedCBItem, value);
FilteredBills.Refresh();
}
}
}
uj5u.com熱心網友回復:
第二個 tabitem 上的資料網格正在顯示應用程式加載的所有資料
那是因為您將AllBills
視圖模型的屬性的源設定為AllBills
包含(?)所有專案的模型的屬性。如果您希望它為空,則不要將其設定為Source
包含任何專案的串列:
public BillsViewModel()
{
cvsFiltered.Source = m.FilteredBills;
}
當我在組合框中選擇或鍵入有效專案時,第二個 tabitem 上的資料網格未顯示過濾后的資料
如果我正確理解您的問題,那么您應該在屬性的設定器中設定Source
of :cvsAll
SelectedCBItem
private string _selectedCBItem;
public string SelectedCBItem
{
get { return _selectedCBItem; }
set
{
_selectedCBItem = value;
cvsAll.Source = m.GetBills_Pen(value); // <--
OnPropertyChanged("SelectedCBItem");
}
}
uj5u.com熱心網友回復:
使用@Firo 顯示的方法,我已經成功地在我的應用程式中實施(所以我將他的答案標記為已接受),這就是我最終得到的結果(以防它幫助任何可能有類似問題的人)
public class Model
{
private List<Bills> _sBills;
public List<Bills> SBills
{
get
{
if (_sBills == null) LoadAllBillsFromDatabase();
return _sBills;
}
}
public List<Bills> FilteredBills { get; private set; }
public void LoadAllBillsFromDatabase()
{
SQLiteConnection m_dbConnection = new SQLiteConnection(@"Data Source=Bills.db;");
SQLiteCommand sqlCom = new SQLiteCommand(@"Select * From billdata", m_dbConnection);
SQLiteDataAdapter sda = new SQLiteDataAdapter(sqlCom);
DataTable dt = new DataTable();
sda.Fill(dt);
_sBills = new List<Bills>();
foreach (DataRow row in dt.Rows)
{
_sBills.Add(new Bills()
{
Id = Convert.ToInt32(row["Id"]),
Party = (string)row["Party"],
BillNo = (string)row["BillNo"],
BillDt = (string)(row["BillDt"]),
Amt = (string)row["Amt"],
DueDt = (string)(row["DueDt"]),
PaidOn = (string)(row["PaidOn"])
});
}
m_dbConnection.Close();
}
}
public class BillsViewModel : ViewModelBase
{
CollectionViewSource cvsAll = new CollectionViewSource();
private List<Bills> _allBills;
public BillsViewModel()
{
cvsAll.Source = m.FilteredBills;
_allBills = m.SBills;
AllBills = new ListCollectionView(_allBills)
{
Filter = o => ((Bills)o).PaidOn==""
};
ComboItems = _allBills.Select(b => b.Party).Distinct().OrderBy(b => b).ToList();
FilteredBills = new ListCollectionView(_allBills)
{
Filter = o => ((Bills)o).Party == SelectedCBItem && ((Bills)o).PaidOn==""
};
}
Model m = new Model();
public ICollectionView AllBills { get; private set; }
public ICollectionView FilteredBills { get; private set; }
public List<string> ComboItems { get; private set; }
private string _selectedCBItem;
public string SelectedCBItem
{
get { return _selectedCBItem; }
set
{
SetValue(ref _selectedCBItem, value);
FilteredBills.Refresh();
}
}
}
第一個 tabitem 的 datagrid 中的AllBills
itemsource 是,第二個 tabitem 的 datagrid 中的 itemsource 是FilteredBills
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/492185.html