I am new to wpf and fighting with this issue for several days. I have a combobox which has dataview as itemssource. It displays the values correctly but selecteditem is always null when i re-run the application.
ChargeCodeValidValues objects that combobox is bound to:
public class ChargeCodeValidValues
{
#region Properties
public DataTable ChargeCodesValidValuesTable { get; set; }
public DataView dvChargeCodeValidValues { get; set; }
#endregion
#region Constructor
public ChargeCodeValidValues()
{
LoadChargeCodesValidValues();
}
public void LoadChargeCodesValidValues()
{
Database db = new Database();
DataTable dataTable = db.ExecuteQuery("upGet_ChargeCodesValidValues", "ChargeCodesValidValues", "ID");
this.ChargeCodesValidValuesTable = dataTable;
this.dvChargeCodeValidValues = ChargeCodesValidValuesTable.DefaultView;
}
XAML:
<DataTemplate x:Key="combodescriptionTemplate">
<ComboBox Name="cboCombo"
Loaded="cboCombo_Loaded">
<ComboBox.DataContext>
<Objects:ChargeCodeValidValues/>
</ComboBox.DataContext>
</ComboBox>
</DataTemplate>
<local:TotalCellTemplateSelector x:Key="totalcellTemplateSelector"
combodescriptionTemplate="{StaticResource combodescriptionTemplate}"/>
gridview column :
<dxg:GridColumn Header="Description" FieldName="Description" Width="Auto" MinWidth="132" AllowMoving="False" CellTemplateSelector="{StaticResource totalcellTemplateSelector}" /> -->
this column is textbox by default. It changes to combobox based on values from other column
code:
private void cboCombo_Loaded(object sender, RoutedEventArgs e)
{
ComboBox cmb = sender as ComboBox;
DataTable dtChargeCodeValidValues = oChargeCodesValidvalues.ChargeCodesValidValuesTable.Copy();
DataView dvCurrentCodeValues = dtChargeCodeValidValues.Copy().DefaultView;
cmb.ItemsSource = dvCurrentCodeValues;
cmb.DisplayMemberPath = "Description";
cmb.SelectedValuePath = "Description";
cmb.SelectedValue = "Description";
}
There is no magic that will persist a selection in a ComboBox across different invocations of your application; you'll have to write the code yourself. For example:
<ComboBox
x:Name="comboBox"
SelectionChanged="OnSelectionChanged"
Loaded="OnComboBoxLoaded"
>
<ComboBox.Items>
<system:String>One</system:String>
<system:String>Two</system:String>
<system:String>Three</system:String>
</ComboBox.Items>
</ComboBox>
...with the following code-behind:
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
int index = comboBox.SelectedIndex;
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = store.CreateFile("selectedIndex"))
{
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(index.ToString());
}
}
}
}
private void OnComboBoxLoaded(object sender, RoutedEventArgs e)
{
int index = GetPreviousIndex();
comboBox.SelectedIndex = index;
comboBox.Text = comboBox.Items[index] as string;
}
private int GetPreviousIndex()
{
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = store.OpenFile("selectedIndex", FileMode.Open))
{
using (BinaryReader reader = new BinaryReader(stream))
{
try
{
return int.Parse(reader.ReadString());
}
catch (Exception x)
{
return -1;
}
}
}
}
}
Note that setting the SelectedIndex is insufficient; you have to set the Text property as well, or you won't see the selection without opening the ComboBox.
There are many ways of persisting the selection, of course; here I just cobbled something together quickly (and somewhat dirtily).
Related
I'm working on a C# application, where I'm trying to create my own filtering mechanism for filtering a Telerik RadGridView control.
My RadGridView control looks as follows (in the xaml file, I've left some open lines for showing the part where I define my filter):
<telerik:RadGridView x:Name="PartsGridView"
AutoGenerateColumns="False"
CanUserFreezeColumns="False"
FilteringMode="Popup"
FilterOperatorsLoading="Grid_FilterOperatorsLoading"
ItemsSource="{Binding PagedSource, ElementName=PartsRadDataPager}"
IsSynchronizedWithCurrentItem="False"
SelectedItem="{Binding SelectedPart}"
SelectionMode="Single"
ShowInsertRow="False"
EnableRowVirtualization="True"
RowLoaded="PartsGridView_RowLoaded"
FieldFilterEditorCreated="FieldFilterEditorCreated"
IsFilteringAllowed="True"
DistinctValuesLoading="PartsGridView_DistinctValuesLoading"
Grouped="PartsGridView_Grouped">
<telerik:RadGridView.GroupDescriptors>
<telerik:GroupDescriptor Member="Name" DisplayContent="Article"/>
</telerik:RadGridView.GroupDescriptors>
<telerik:RadGridView.FilterDescriptors/>
<telerik:RadGridView.Columns>
...
<telerik:GridViewDataColumn DataMemberBinding="{Binding Article.CustomerReference}"
Header="Client"
IsReadOnly="True"
Name="Client">
<telerik:GridViewDataColumn.FilteringControl>
<local:Myfilter Column="{Binding ElementName=Client}"/>
</telerik:GridViewDataColumn.FilteringControl>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
The corresponding source code is as follows (I've only shown the OnFilter, it's the idea to extend the filtering possibilities to regular expressions, but let's start making the regular filter work first):
public partial class MyFilter : System.Windows.Controls.UserControl,
IFilteringControl
{
private GridViewDataColumn column;
private CompositeFilterDescriptor compositeFilter;
private Telerik.Windows.Data.FilterDescriptor textFilter;
private void OnFilter(object sender, RoutedEventArgs e)
{
//var reg = new Regex(textBox.Text.Replace("*", ".*"));
// var descriptor = new FilterDescriptor<string>
// { FilteringExpression = o => reg.IsMatch(o) };
compositeFilter = new CompositeFilterDescriptor();
textFilter = new Telerik.Windows.Data.FilterDescriptor(Column.Name
, Telerik.Windows.Data.FilterOperator.IsEqualTo
, null);
compositeFilter.FilterDescriptors.Add(textFilter);
textFilter.Value = TextBox;
if (!Column.DataControl.FilterDescriptors.Contains(compositeFilter))
{
Column.DataControl.FilterDescriptors.Add(compositeFilter);
}
IsActive = true;
}
When debugging, I go into the OnFilter() function but instead of just filtering, I don't see any data in the RadGridView anymore.
Does anybody have an idea what I'm doing wrong?
Edit: In case the question is not clear, don't hesitate asking for more information.
Try this:
private void OnFilter(object sender, RoutedEventArgs e)
{
//var reg = new Regex(textBox.Text.Replace("*", ".*"));
// var descriptor = new FilterDescriptor<string>
// { FilteringExpression = o => reg.IsMatch(o) };
//compositeFilter = new CompositeFilterDescriptor();
textFilter = new Telerik.Windows.Data.FilterDescriptor(Column.Name
, Telerik.Windows.Data.FilterOperator.IsEqualTo
, null);
//compositeFilter.FilterDescriptors.Add(textFilter);
textFilter.Value = TextBox;
if (!Column.DataControl.FilterDescriptors.Contains(textFilter))
{
Column.DataControl.FilterDescriptors.Add(textFilter);
}
IsActive = true;
}
u can also try this:
private void OnFilter(object sender, RoutedEventArgs e)
{
compositeFilter = new CompositeFilterDescriptor();
textFilter = new Telerik.Windows.Data.FilterDescriptor(Column.Name, Telerik.Windows.Data.FilterOperator.IsEqualTo, null);
compositeFilter.FilterDescriptors.Add(textFilter);
textFilter.Value = TextBox;
if (!Column.DataControl.FilterDescriptors.Contains(compositeFilter))
{
Column.DataControl.FilterDescriptors.Add(compositeFilter);
}
IsActive = true;
}
I use SearchBar to search from listView and I have other controls
but when page load just SearchBar appear and other controls disappear
like this image
and when search then select from listView the disappeared controls appears
like this image
my xaml code :
<StackLayout>
<SearchBar x:Name="search_trade"
TextChanged="search_trade_TextChanged"
/>
<ListView x:Name="list" ItemSelected="list_ItemSelected" >
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" ></TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Editor x:Name="edit_trade"
FontSize="14"/>
</StackLayout>
my c# code :
private void search_trade_TextChanged(object sender, TextChangedEventArgs e)
{
if (search_trade.Text.Trim()==string.Empty)
{
list.IsVisible = false;
}
list.IsVisible = true;
if (string.IsNullOrEmpty(e.NewTextValue))
{
list.ItemsSource = tempdata;
}
else
{
list.ItemsSource = tempdata.Where(x => x.Name.ToLower().StartsWith(e.NewTextValue));
}
}
private void list_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (Contacts)e.SelectedItem;
edit_trade.Text = item.Name.ToString();
search_trade.Text = "";
list.IsVisible = false;
edit_trade.IsReadOnly = true;
}
code c# that I initially set the ItemsSource :
public Anti_biotic()
{
InitializeComponent();
active();
years_months();
frame_view.IsVisible = false;
trade();
}
private void trade()
{
tempdata = new List<Contacts>
{
new Contacts() { Name = "Amoclawin228.5mg/5mlsusp60ml"},
new Contacts() { Name = "Amoclawin 457mg / 5ml susp 60 ml"},
new Contacts() { Name = "Amoflux 250 mg susp 100 ml"},
};
}
how can I solve this issue?
you are not assigning the ListView's ItemsSource when the page loads. If the ListView doesn't have any data then it won't display anything
public Anti_biotic()
{
InitializeComponent();
active();
years_months();
frame_view.IsVisible = false;
// this method creates tempdata but doesn't do anything with it
trade();
// add this
list.ItemsSource = tempdata;
}
The DataGrid columns are dynamically created in code behind. In order to bind the columns dynamically I have a Dictionary<string, obj> property, with the key as the column header, and the values.
and the columns gets bound to the dictionary like this:
var item = new DataGridTextColumn();
item.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
item.Header = name;
item.Binding = new Binding($"di[{name}].obj") { Mode = BindingMode.TwoWay };
It works fine, but I couldn't figure out how to get the values from the new row form DataGrid
I've created a test project and ExpandoObject worked for me. I was able to display dynamic column "FirstName" and also add new rows by editing grid rows
XAML:
<Grid Margin="0,0,0,56" Loaded="Grid_Loaded_1">
<DataGrid Name="MyGrid" ItemsSource="{Binding Items}" HorizontalAlignment="Left" Margin="69,33,0,0" VerticalAlignment="Top" Height="220" Width="389"/>
<Button Content="Button" HorizontalAlignment="Left" Height="22" Margin="339,286,0,-45" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
</Grid>
CS:
public partial class MainWindow : Window
{
public ViewModel Vm { get; set; }
public MainWindow()
{
InitializeComponent();
}
private void Grid_Loaded_1(object sender, RoutedEventArgs e)
{
Vm = new ViewModel();
Vm.Items = new ObservableCollection<ExpandoObject>();
DataContext = Vm;
var fieldName = "FirstName";
var item = new ExpandoObject() as IDictionary<string, Object>;
item.Add(fieldName, "Adam"); // Dynamically adding new fields
var eoItem = item as ExpandoObject;
Vm.Items.Add(eoItem);
// Dynamically adding new columns
var col = new DataGridTextColumn();
col.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);
col.Header = fieldName;
col.Binding = new Binding(fieldName) { Mode = BindingMode.TwoWay };
MyGrid.Columns.Add(col);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
public class ViewModel
{
public ObservableCollection<ExpandoObject> Items { get; set; }
}
I had similar problem some time ago. Below You can find my solution. Basically I needed to change AddingNewRow event. You will need to change types etc. to meet your needs but this should be rather easy.
private void AddingNewRow(object sender, AddingNewItemEventArgs e)
{
DictionaryRowData newRow = new DictionaryRowData();
for (int i = 0; i < dictionaryData.Columns.Count; i++)
{
newRow.Cells.Add(new DictionaryCellData());
}
e.NewItem = newRow;
}
Sorry, for not matching exactly your case, but I don't have time right now. I hope it will help
I have a datagridview that is not bound to a table in a database. The datagridview is being populated by the contents of a drop down list and a text box on a button click. I want to prevent the records from being deleted everytime I close the form. Is there a way for the records in the datagridview to be saved without having to create a database table?
Below is my code:
private void btnInsert_Click(object sender, EventArgs e)
{
this.dgInsertedInfo.Rows.Add(ddlVendorID.Text, txtDate.Text);
}
You have many options. Here is a simple solution that uses XML serialization.
Note that it makes a few assumptions:
The data all are strings
The DataGridView already has all the columns
To save the other data types you should create a serializable structure!
private void saveButton_Click(object sender, EventArgs e)
{
List<List<string>> data = new List<List<string>>();
foreach(DataGridViewRow row in dgInsertedInfo.Rows)
{
List<string> rowData = new List<string>();
foreach (DataGridViewCell cell in row.Cells)
rowData.Add(cell.FormattedValue.ToString());
data.Add(rowData);
}
XmlSerializer xs = new XmlSerializer(data.GetType());
using (TextWriter tw = new StreamWriter(yourFileName))
{
xs.Serialize(tw, data);
tw.Close();
}
}
private void loadButton_Click(object sender, EventArgs e)
{
List<List<string>> data = new List<List<string>>();
XmlSerializer xs = new XmlSerializer(data.GetType());
using (TextReader tr = new StreamReader(yourFileName))
data = (List<List<string>>) xs.Deserialize(tr);
foreach (List<string> rowData in data)
dgInsertedInfo.Rows.Add(rowData.ToArray());
}
You can write your OWN class and save it as a setting-property.
Class Settings:
namespace MyNamespace
{
public class Settings
{
private ObservableCollection DataGridItemsProp;
public ObservableCollection DataGridItems
{
get { return DataGridItemsProp; }
set { DataGridItemsProp = value; }
}
}
}
Get and save your setting:
//get settings
var datagrid = Properties.Settings.Default.UserSettings;
//save settings
Properties.Settings.Default.UserSettings= datagrid;
Properties.Settings.Default.Save();
I want to create a auto complete tools using combobox.
So i just add some items to my combobox .And set these items as a source of my combobox.
In form_load i do this:
private void frmInvoice_Load(object sender, EventArgs e)
{
comboBox1.AutoCompleteMode=AutoCompleteMode.Append;
comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
But it doesn't work and when i type a letter the whole word doesn't appear in combobox.Why ?
i follow this link :http://www.c-sharpcorner.com/UploadFile/mahesh/AutoCompletion02012006113508AM/AutoCompletion.aspx
best regards.
Since you've declared CustomSource for auto completion, you should provide that source:
private void frmInvoice_Load(object sender, EventArgs e)
{
comboBox1.AutoCompleteMode=AutoCompleteMode.Append;
comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
AutoCompleteStringCollection data = new AutoCompleteStringCollection();
// Put here the auto completions' e.g.
data.Add("My String 1");
data.Add("Autocompletion 2");
data.Add("Some stuff");
comboBox1.AutoCompleteCustomSource = data;
}
You didn't upload your CustomSource.
public Form1()
{
InitializeComponent();
this.comboBox1.AutoCompleteCustomSource.AddRange
(new string[] {"Raj Beniwal", "Rohit Malhotra", "Ronit Singh", "Ravi Kumar",
"Rohit Behl", "Sanjay Singh", "Shalini Singh", "Seema Malhotra", "Savi Verma",
"Karan Kappor", "Kapil Malhotra", "Vikash Nanda", "Vikram Jain", "Amit Garg",
"Atul Wadhwani", "Ashwani Pandey"
});
this.comboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
this.comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
}
Refference from : http://www.c-sharpcorner.com/Blogs/2050/autocomplete-combobox-in-visual-C-Sharp-2010.aspx
What I have done is use a 3rd party dlls. These are of Telerik. My code is as follows
<telerik:RadComboBox x:Name="radComboBox" VerticalAlignment="Top" Visibility="Visible" AllowDrop="True"
ItemsSource="{Binding AvailList}" SelectedItem="{Binding SelectedComboboxItem, Mode=TwoWay}"
IsEditable="True"
telerik:TextSearch.TextPath="DisplayName" Height="17" Margin="10,34,39,0" />
This is in xaml. It directly reads from the ItemSource and does the autocompletion.
Or you can do this...
private void LoadStuffNames()
{
try
{
string Query = "select stuff_name from dbo.stuff";
string[] names = GetColumnData_FromDB(Query);
comboName.AutoCompleteMode = AutoCompleteMode.Suggest;
comboName.AutoCompleteSource = AutoCompleteSource.CustomSource;
AutoCompleteStringCollection x = new AutoCompleteStringCollection();
if (names != null && names.Length > 0)
foreach (string s in names)
x.Add(s);
comboName.AutoCompleteCustomSource = x;
}
catch (Exception ex)
{
}
finally
{
}
}
Cheers..