我目前正在构建一个从SQL服务器导入数据的GUI。
我目前正在使用ComboBox来允许用户选择他想要访问的Category / Sub_Category。 > Image
我无法弄清楚如何确定位于“类别”列的行中的数据是否具有相同的值,如果是,则确定它们是否列出了Sub_Category。
Sub_Categories应仅与其对应的类别同步,而不是所有类别,因此我需要想出一种方法将sub_categories和类别配对在一起。
如果WHOLE类别不存在Sub_Category,则Sub_Category_ComboBox应设置为不可编辑(IsEditable = false),因为它们没有值。
如果某个类别包含Sub_Category,则SubCategory_ComboBox应仅显示与特定类别同步的Sub_Categories。 (不知道如何同步它们。)
DDL:
--------------------------## Heading ##------------------------------
-- DDL for Table OP_MAIN_COLLECTIONS
--------------------------------------------------------
CREATE TABLE "SCHEMA"."OP_MAIN_COLLECTIONS"
( "PRIMARY_KEY" NUMBER(*,0),
"CATEGORY" VARCHAR2(4000 CHAR),
"SUB_CATEGORY" VARCHAR2(4000 CHAR),
"NAME" VARCHAR2(4000 CHAR),
"SCHEDULE" CLOB,
"INTERNAL_NAME" VARCHAR2(4000 CHAR),
"COMMENTS" CLOB,
"START_DATE" DATE,
"END_DATE" DATE,
"SCHEDULED_OR_UNSCHEDULED" NUMBER(*,0)
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SCHEMA"
LOB ("SCHEDULE") STORE AS BASICFILE "SYS_LOB0000315099C00005$$"(
TABLESPACE "SCHEMA" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
NOCACHE LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT))
LOB ("COMMENTS") STORE AS BASICFILE (
TABLESPACE "SCHEMA" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION
NOCACHE LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)) ;
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."PRIMARY_KEY" IS 'PK as INT';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."CATEGORY" IS 'A Category will only display if the user has the proper rights/privledges to read it, as will all data within'' a category.';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."SUB_CATEGORY" IS 'Column (Variable) that allows for sub_categories to exist. Can be Null.';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."NAME" IS 'Name of Operation: Limited to 50 Characters atm';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."SCHEDULE" IS 'Schedule EX: "5AM - 11PM(ET), EVERY 30 MINUTES*, MON THRU SUN" (Can end up being rather large so made it a clob).';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."INTERNAL_NAME" IS 'Job_Name set to VarChar(120)';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."COMMENTS" IS 'Any job comments that may exist will be located here. May be rather large, so it was made a CLOB just incase.';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."START_DATE" IS 'Start Date variable that allows for Procedure to be hidden until date set.';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."END_DATE" IS 'End Date variable that allows for Procedure to be Removed once the date listed is reached.';
COMMENT ON COLUMN "SCHEMA"."OP_MAIN_COLLECTIONS"."SCHEDULED_OR_UNSCHEDULED" IS 'Neccessary Information to determine whether or not the event has been scheduled or not. (Limited to a value of 0 or 1). - If 0, unscheduled | if 1, scheduled.';
--------------------------------------------------------
-- DDL for Index OP_SCHEDULED_PK
--------------------------------------------------------
CREATE UNIQUE INDEX "SCHEMA"."OP_SCHEDULED_PK" ON "SCHEMA"."OP_MAIN_COLLECTIONS" ("PRIMARY_KEY")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SCHEMA" ;
ALTER INDEX "SCHEMA"."OP_SCHEDULED_PK" UNUSABLE;
--------------------------------------------------------
-- Constraints for Table OP_MAIN_COLLECTIONS
--------------------------------------------------------
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("SCHEDULED_OR_UNSCHEDULED" NOT NULL ENABLE);
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" ADD CONSTRAINT "SCHEDULED_OR_UNSCHEDULED" CHECK (SCHEDULED_OR_UNSCHEDULED >= 0 AND SCHEDULED_OR_UNSCHEDULED < 2) ENABLE;
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" ADD CONSTRAINT "OP_SCHEDULED_PK" PRIMARY KEY ("PRIMARY_KEY")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "SCHEMA"
ALTER INDEX "SCHEMA"."OP_SCHEDULED_PK" UNUSABLE; ENABLE;
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("COMMENTS" NOT NULL ENABLE);
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("INTERNAL_NAME" NOT NULL ENABLE);
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("SCHEDULE" NOT NULL ENABLE);
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("NAME" NOT NULL ENABLE);
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("CATEGORY" NOT NULL ENABLE);
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" MODIFY ("PRIMARY_KEY" NOT NULL ENABLE);
--------------------------------------------------------
-- Ref Constraints for Table OP_MAIN_COLLECTIONS
--------------------------------------------------------
ALTER TABLE "SCHEMA"."OP_MAIN_COLLECTIONS" ADD CONSTRAINT "CATEGORY" FOREIGN KEY ("PRIMARY_KEY")
REFERENCES "SCHEMA"."OP_MAIN_COLLECTIONS" ("PRIMARY_KEY") ENABLE;
--------------------------------------------------------
-- DDL for Trigger AUD_UPDATE
--------------------------------------------------------
CREATE OR REPLACE TRIGGER "SCHEMA"."AUD_UPDATE"
after update on OP_MAIN_COLLECTIONS
for each row
begin
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'PRIMARY_KEY', :new.PRIMARY_KEY, :old.PRIMARY_KEY);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'CATEGORY', :new.CATEGORY, :old.CATEGORY);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'SUB_CATEGORY', :new.SUB_CATEGORY, :old.SUB_CATEGORY);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'NAME', :new.NAME, :old.NAME);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'SCHEDULE', :new.SCHEDULE, :old.SCHEDULE);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'INTERNAL_NAME', :new.INTERNAL_NAME, :old.INTERNAL_NAME);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'COMMENTS', :new.COMMENTS, :old.COMMENTS);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'START_DATE', :new.START_DATE, :old.START_DATE);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'END_DATE', :new.END_DATE, :old.END_DATE);
AUDIT_PACKAGE.check_val( 'OP_MAIN_COLLECTIONS', 'SCHEDULED_OR_UNSCHEDULED', :new.SCHEDULED_OR_UNSCHEDULED, :old.SCHEDULED_OR_UNSCHEDULED);
end;
/
ALTER TRIGGER "SCHEMA"."AUD_UPDATE" ENABLE;
C#:
/*
* What we're trying to do:
*
* First, determine whether or not the row(s) data for the Category column have data for the Sub_Category column or if the Category data contains the same values (names, EX: BillTrak Pro), then sort them accordingly.
** Sub_Categories should only Sync with their corresponding Categories, not all Categories.
*
*
* Conditionals for the Category data pertaining to Sub_Category(s):
** If no Sub_Category(s) exist for the WHOLE Category, then > Sub_Category_ComboBox should be set to read ONLY(IsEnabled = false) and the four ListView's should just display single Category Information.
*
*
** If Category(s) contain Sub_Category(s), then SubCategory_ComboBox should display only the Sub_Categories that are Sync'd to the specific Category(s).
* Row Data should be sorted, first by Category, then Sub_Category, then displayed only when their Sub_Category is displayed via the SubCategory_ComboBox.
* The four ListView's data should only display data, coresponding to the SubCategory_ComboBox data.
*
*/
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
WpfApplication1.DataSet1 dataSet1 = ((WpfApplication1.DataSet1)(this.FindResource("dataSet1")));
// Load data into the table OP_MAIN_COLLECTIONS. You can modify this code as needed.
WpfApplication1.DataSet1TableAdapters.OP_MAIN_COLLECTIONSTableAdapter dataSet1OP_MAIN_COLLECTIONSTableAdapter = new WpfApplication1.DataSet1TableAdapters.OP_MAIN_COLLECTIONSTableAdapter();
dataSet1OP_MAIN_COLLECTIONSTableAdapter.Fill(dataSet1.OP_MAIN_COLLECTIONS);
System.Windows.Data.CollectionViewSource oP_MAIN_COLLECTIONSViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("oP_MAIN_COLLECTIONSViewSource")));
oP_MAIN_COLLECTIONSViewSource.View.MoveCurrentToFirst();
WpfApplication1.DataSet2 dataSet2 = ((WpfApplication1.DataSet2)(this.FindResource("dataSet2")));
// Load data into the table OP_TITLE_INFORMATION. You can modify this code as needed.
WpfApplication1.DataSet2TableAdapters.OP_TITLE_INFORMATIONTableAdapter dataSet2OP_TITLE_INFORMATIONTableAdapter = new WpfApplication1.DataSet2TableAdapters.OP_TITLE_INFORMATIONTableAdapter();
dataSet2OP_TITLE_INFORMATIONTableAdapter.Fill(dataSet2.OP_TITLE_INFORMATION);
System.Windows.Data.CollectionViewSource oP_TITLE_INFORMATIONViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("oP_TITLE_INFORMATIONViewSource")));
oP_TITLE_INFORMATIONViewSource.View.MoveCurrentToFirst();
// Load data into the table OP_MAIN_COLLECTIONS. You can modify this code as needed.
WpfApplication1.DataSet2TableAdapters.OP_MAIN_COLLECTIONSTableAdapter dataSet2OP_MAIN_COLLECTIONSTableAdapter = new WpfApplication1.DataSet2TableAdapters.OP_MAIN_COLLECTIONSTableAdapter();
dataSet2OP_MAIN_COLLECTIONSTableAdapter.Fill(dataSet2.OP_MAIN_COLLECTIONS);
System.Windows.Data.CollectionViewSource oP_MAIN_COLLECTIONSViewSource1 = ((System.Windows.Data.CollectionViewSource)(this.FindResource("oP_MAIN_COLLECTIONSViewSource1")));
oP_MAIN_COLLECTIONSViewSource1.View.MoveCurrentToFirst();
}
/**
* Operations Guide Name Display settings.
*/
private void OPGuideName_textBox_TextChanged(object sender, TextChangedEventArgs e)
{
}
/**
* Category_ComboBox Display settings.
*/
private void Category_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
/**
* TO-DO:
* Determine whether or not the row(s) data for the Category column have data for the Sub_Category column
* or if the Category data contains the same values (names, EX: BillTrak Pro), then sort them accordingly.
*/
int id = 1; //Get form category combox
WpfApplication1.DataSet2 DS = ((WpfApplication1.DataSet2)(this.FindResource("dataSet2")));
var cats = DS.Tables[0].AsEnumerable().Select(r => new { Key = r.Field<int>("Primary_Key"), Category = r.Field<string>("Category") }).ToList();
foreach( var cat in cats)
{
//Add category and primary key to combo box
Category_ComboBox.Items.Add(new { cat.Key, cat.Category } );
}
DataRow row = DS.Tables[0].AsEnumerable().Where(r => r.Field<int>("Id") == id).FirstOrDefault();
if (row != default(DataRow))
{
if (row["sub_category"] != DBNull.Value)
{
//There is a sub category
}
else
{
//sub category is null
}
}
else
{
//selected category id does not exists
}
}
/**
* SubCategory_ComboBox Display settings.
*/
private void SubCategory_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
/**
* Purpose:
* Should convert SubCategory_ComboBox to readOnly(IsEnabled = false)
* if the data contained in the SubCategory SQL Column is null && Category doesn't contain any Sub_Categories.
* Else, display SubCategory_ComboBox as normal, sync'd with the corresponding category name.
*
* Currently, This code disables the subcategory combobox completely.
* Need to figure out how to get it to read ONLY the null data, not the entire column.
*/
if (string.IsNullOrEmpty(SubCategory_ComboBox.Text))
{
SubCategory_ComboBox.IsEnabled = false;
}
}
private void sCHEDULEListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}
答案 0 :(得分:1)
在触发Category_ComboBox_SelectionChanged
时尝试以下模板,以确定子类别是否存在。如果从用户输入提供,您也可以检查名称。
var cats = DS.Tables[0].AsEnumerable().Select(r => new { Key = r.Field<int>("Primary_Key"), Category = r.Field<string>("Category") }).ToList();
foreach( var cat in cats)
{
//Add category and primary key to combo box
//combox.addItem(cat.Key, cat.Category)
}
int id = 1; //Get form category combox
DataSet DS = new DataSet(); // your dataset
DataRow row = DS.Tables[0].AsEnumerable().Where(r => r.Field<int>("Id") == id).FirstOrDefault();
if (row != default(DataRow))
{
if (row["sub_category"] != DBNull.Value)
{
//There is a sub category
}
else
{
//sub category is null
}
}
else
{
//selected category id does not exists
}
希望它有所帮助!!
修改强>
//find all categories and populate category
IEnumerable<string> categories = DS.Tables[0].AsEnumerable().Select(r => r.Field<string>("Category")).Distinct();
//once the value in category combobox change
// inside Category_ComboBox_SelectionChanged
string category = "Bill";
//get rows with non null sub categories
IEnumerable<DataRow> rows = DS.Tables[0].AsEnumerable().Where(r => r.Field<string>("Category").ToLower() == category.ToLower() && r["Sub_Category"] != DBNull.Value);
if (rows.Count() == 0)
{
//disable sub category
}
else
{
//get sub categories
IEnumerable<string> sub_cats = rows.Select(r => r.Field<string>("Sub_category")).Distinct();
//populate sub categories
}
修改
使用此循环填充类别
foreach (DataRow row in DS.Tables[0].Rows)
{
int primary_key = row.Field<int>("Primary_Key");
string category = row.Field<string>("Category");
//populate the combo box
}