I have a property defined in Class A. When the property is changed then i need to raise an event. Another class B should respond to this event and do something. I have done something like this:
Code:
Class A{
string variable = "test";
public delegate void EventHandler(object sender, EventArgs args);
public static event EventHandler ThrowAddEvent = delegate { };
public static event EventHandler ThrowRemoveEvent = delegate { };
public String Name { get; set; }
public int Select { get; set; }
public Window Formref1 { get; set; }
public bool IsSelected
{
get { return IsSlctd; }
set
{
IsSlctd = value;
if (value)
{
ThrowAddEvent(this, new EventArgs());
}
else
{
ThrowRemoveEvent(this, new EventArgs());
}
}
}
}
Another class which is responding to this event is defined as follows:
Class B{
public B(ParsedResult _result)
{
InitializeComponent();
if (_result != null)
{
this.Result = _result;
PopulateColumns1();
DataGrid1.Items.Clear();
DataGrid1.ItemsSource = Populatevariables();
}
}
public void PopulateColumns1()
{
DataGridTextColumn Colvar = new DataGridTextColumn();
Colvar.Header = "Variables";
Colvar.Binding = new Binding("Name");
DataGrid1.Columns.Add(Colvar);
DataGridTemplateColumn Col = new DataGridTemplateColumn();
Col.Header = "Select";
DataTemplate dd = new DataTemplate();
FrameworkElementFactory FF = new FrameworkElementFactory(typeof(CheckBox));
FF.SetBinding(CheckBox.BindingGroupProperty, new Binding("Select"));
FF.SetBinding(CheckBox.IsCheckedProperty, new Binding("IsSelected") { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged });
FF.SetValue(FrameworkElement.HorizontalAlignmentProperty, HorizontalAlignment.Center);
dd.VisualTree = FF;
Col.CellTemplate = dd;
DataGrid1.Columns.Add(Col);
}
private List<A> PopulateVariables()
{
CheckBox cb = new CheckBox();
List<A> CharList = new List<A>();
Result.GetCharacteristicList.MoveNext();
IEnumerator<A2LCharacteristic> enumeratorlist = Result.GetCharacteristicList;
for (int i = 0; enumeratorlist.MoveNext(); i++)
{
CharList.Add(new A() { Name = enumeratorlist.Current.Name, Select = i, Formref1 = this});
}
enumeratorlist.Reset();
return CharList;
}
private void OKBtn_Click(object sender, RoutedEventArgs e)
{
A Instance_A = new A();
Instance_A.ThrowAddEvent += (sender1, args) => { Addvrbl(Instance_A.variable); };
Instance_A.ThrowRemoveEvent += (sender2, args) => { RmvVrbl(Instance_A.variable); };
this.Close();
}
public void Addvrbl(string vrbl)
{
if (!(vrbllist.Contains(vrbl)))
{
vrbllist.Add(vrbl);
}
}
public void RmvVrbl(string vrbl)
{
if ((vrbllist.Contains(vrbl)))
{
vrbllist.Remove(vrbl);
}
}
}
The problem is it is not going inside the method "AddVrbl" and "RmvVrbl". I have used the solution from here. Please help.
OK, instead of subscribing to the event of a new instance of A,which will never get triggered/published. When you initializing CharList, you have to subscribe to the event of each A item.
Something like:
for (int i = 0; enumeratorlist.MoveNext(); i++)
{
var obja=new A() { Name = enumeratorlist.Current.Name, Select = i, Formref1 = this};
obja.ThrowAddEvent += ...
obja.ThrowRemoveEvent += ...
CharList.Add(obja);
}
PS: Make sure you un-subscribe these events before removing an item from your CharList.
Related
I create WebChannelFactory. I need set KeepAlive=false.
I found only one solution use CustomBinding. and set property keepAliveEnabled to false.
I use custom behavior for my factory also.
Code:
static CustomBinding GetBinding(MySettings serviceSettings = null)
{
var customBinding = new CustomBinding();
HttpTransportBindingElement transportBindingElement = new HttpTransportBindingElement();
transportBindingElement.KeepAliveEnabled = false;
transportBindingElement.MaxBufferSize = 0x07000000;
transportBindingElement.MaxReceivedMessageSize = 0x07000000;
if (serviceSettings != null)
{
customBinding.SendTimeout = serviceSettings.SendTimeout;
}
customBinding.Elements.Add(transportBindingElement);
return customBinding;
}
var customBinding = GetBinding(serviceSettings);
WebChannelFactory<TChannel> factory = new WebChannelFactory<TChannel>(customBinding, new Uri(url));
factory.Endpoint.Behaviors.Add(new MyWebHttpBehavior(userId));
class MyWebHttpBehavior : IEndpointBehavior
{
private int _userId;
public MyWebHttpBehavior(int userId)
{
_userId = userId;
}
public void AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{ }
public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)
{
behavior.MessageInspectors.Add(new MyClientMessageInspector(_userId));
}
public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{ }
public void Validate(ServiceEndpoint serviceEndpoint)
{ }
}
In current situation i get error "does not have a Binding with the None MessageVersion".
I would like to get the form as datasource when i click combo box. How could i achieve this. Please give suggestion.
I've created a PopupComboBox class which inherits from the standard Windows Forms ComboBox. It has a Title property that you can set which will be used on the popup window when the combo is clicked.
public class PopupComboBox : ComboBox
{
private string title;
public string Title
{
get { return this.title; }
set { this.title = value; }
}
public PopupComboBox() : base()
{
}
public PopupComboBox (string title)
: base()
{
this.title = title;
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
// Show the popup form
var popup = new SelectItemForm(this.title, this);
var result = popup.ShowDialog(this);
if (result == DialogResult.OK)
{
// Select this item in the ComboBox
SelectedIndex = this.FindStringExact(popup.SelectedDisplay);
}
}
}
When you click on the combo, a popup form will come up (source code below for SelectItemForm). It uses the DataSource, ValueMember and DisplayMember of the parent PopupComboBox to populate a ListView with the list of items from the combo. When you click on OK, it will save the selected item in the SelectedValue and SelectedDisplay properties so that we can select that item in the ComboBox when the form closes.
public partial class SelectItemForm : Form
{
public object SelectedValue { get; private set; }
public string SelectedDisplay { get; private set; }
public SelectItemForm(string title, PopupComboBox parent)
:base()
{
InitializeComponent();
this.Text = title;
// Add items to the list
foreach (var item in parent.Items)
{
// Get the display and value member properties for this combo box
// and use them for the Code/Name columns in the popup form
var props = item.GetType().GetProperties();
var code = props.Where(p => p.Name == parent.ValueMember).Single().GetValue(item);
var name = props.Where(p => p.Name == parent.DisplayMember).Single().GetValue(item);
listView.Items.Add(new ListViewItem(
new string[] { code.ToString(), name.ToString() }));
}
}
private void btnOk_Click(object sender, EventArgs e)
{
if (listView.SelectedItems != null && listView.SelectedItems.Count > 0)
{
SelectedValue = listView.SelectedItems[0].Text;
SelectedDisplay = listView.SelectedItems[0].SubItems[1].Text;
DialogResult = DialogResult.OK;
}
else
{
MessageBox.Show(this, "Select an item first", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
}
}
Here is the designer part of the form, where you can see what properties I've changed for the ListView to look like it does:
partial class SelectItemForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.listView = new System.Windows.Forms.ListView();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.Code = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.Value = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.SuspendLayout();
//
// listView
//
this.listView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.Code,
this.Value});
this.listView.FullRowSelect = true;
this.listView.GridLines = true;
this.listView.Location = new System.Drawing.Point(3, 3);
this.listView.MultiSelect = false;
this.listView.Name = "listView";
this.listView.Size = new System.Drawing.Size(432, 170);
this.listView.TabIndex = 0;
this.listView.UseCompatibleStateImageBehavior = false;
this.listView.View = System.Windows.Forms.View.Details;
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Location = new System.Drawing.Point(272, 179);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(75, 23);
this.btnOk.TabIndex = 1;
this.btnOk.Text = "OK";
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.Location = new System.Drawing.Point(353, 179);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// Code
//
this.Code.Text = "Code";
this.Code.Width = 108;
//
// Value
//
this.Value.Text = "Name";
this.Value.Width = 296;
//
// SelectItemForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(440, 214);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnOk);
this.Controls.Add(this.listView);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SelectItemForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Title";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView listView;
private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.ColumnHeader Code;
private System.Windows.Forms.ColumnHeader Value;
}
I've also created a small test form where you can test out the functionality of the PopupComboBox, using a small list of products. You'll need to add a PopupComboBox to the form in the designer, and call it comboPopup.
public partial class TestForm : Form
{
public class Product
{
public string Code { get; set; }
public string Name { get; set; }
}
public TestForm()
{
InitializeComponent();
}
private void TestForm_Load(object sender, EventArgs e)
{
var products = new List<Product>();
products.Add(new Product { Code = "0001", Name = "Coca Cola" });
products.Add(new Product { Code = "0002", Name = "Mountain Dew" });
products.Add(new Product { Code = "0003", Name = "Sprite Zero" });
comboPopup.DataSource = products;
comboPopup.DisplayMember = "Name";
comboPopup.ValueMember = "Code";
}
}
whenever a change is occured changes i call this set_filelist_inventory(). and send a new list to this function but UI is not upadating.
public partial class Inventory : UserControl
{
public List<String> file_list = new List<String>();
public void set_filelist_inventory(List<string> x)
{
if (file_list.SequenceEqual(x)) { }
else
{
file_list = x;
Dispatcher.Invoke(() =>
{
listview1.ItemsSource = file_list;
});
}
}
public Inventory()
{
InitializeComponent();
file_list = General.GetFileList();
Discover d = new Discover();
d.send(d);
listview1.ItemsSource = file_list;
}
}
I tried removing if else block. it still didn't worked.
I want to dynamically load and store the Datagrid column widths from my ini file. Write to my inifile for every resize of the column width. Which event can i ues for this. Could any body give any Suggetions or sample code for this.
i use apllicationsettings within a behavior for such things and save the information on application exit.
usage
<DataGrid>
<i:Interaction.Behaviors>
<local:DataGridBehavior GridSettings="{Binding Source={x:Static local:MySettings.Instance},Mode=OneWay}" />
</i:Interaction.Behaviors>
</DataGrid>
settings
[SettingsManageabilityAttribute(SettingsManageability.Roaming)]
public sealed class MySettings: ApplicationSettingsBase, IGridSettings
{
private static readonly Lazy<MySettings> LazyInstance = new Lazy<MySettings>(() => new KadiaSettings());
public static MySettingsInstance { get { return LazyInstance.Value; } }
[UserScopedSettingAttribute()]
[DefaultSettingValue("")]
[SettingsSerializeAs(SettingsSerializeAs.Xml)]
public SerializableDictionary<string, int> GridDisplayIndexList
{
get { return (SerializableDictionary<string, int>)this["GridDisplayIndexList"]; }
set { this["GridDisplayIndexList"] = value; }
}
[UserScopedSettingAttribute()]
[DefaultSettingValue("")]
[SettingsSerializeAs(SettingsSerializeAs.Xml)]
public SerializableDictionary<string, Visibility> GridColumnVisibilityList
{
get { return (SerializableDictionary<string, Visibility>)this["GridColumnVisibilityList"]; }
set { this["GridColumnVisibilityList"] = value; }
}
[UserScopedSettingAttribute()]
[DefaultSettingValue("")]
[SettingsSerializeAs(SettingsSerializeAs.Xml)]
public SerializableDictionary<string, double> GridColumnWidthList
{
get { return (SerializableDictionary<string, double>)this["GridColumnWidthList"]; }
set { this["GridColumnWidthList"] = value; }
}
private MySettings()
{
Application.Current.Exit += OnExit;
}
private void OnExit(object sender, ExitEventArgs e)
{
this.Save();
}
}
public interface IGridSettings: INotifyPropertyChanged
{
SerializableDictionary<string, int> GridDisplayIndexList { get; }
SerializableDictionary<string, Visibility> GridColumnVisibilityList { get; }
SerializableDictionary<string, double> GridColumnWidthList { get; }
}
[XmlRoot("Dictionary")]
public class SerializableDictionary<TKey, TValue>: Dictionary<TKey, TValue>, IXmlSerializable
{
#region IXmlSerializable Members
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
var keySerializer = new XmlSerializer(typeof(TKey));
var valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
reader.ReadStartElement("item");
reader.ReadStartElement("key");
var key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement("value");
var value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
var keySerializer = new XmlSerializer(typeof(TKey));
var valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement("item");
writer.WriteStartElement("key");
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement("value");
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
behavior
public class DataGridBehavior : Behavior<DataGrid>
{
public static readonly DependencyProperty GridSettingsProperty =
DependencyProperty.Register("GridSettings", typeof(IGridSettings), typeof(DataGridBehavior), null);
public IGridSettings GridSettings
{
get { return (IGridSettings)GetValue(GridSettingsProperty); }
set { SetValue(GridSettingsProperty, value); }
}
public DataGridICollectionViewSortMerkerBehavior()
{
Application.Current.Exit += CurrentExit;
}
private void CurrentExit(object sender, ExitEventArgs e)
{
SetSettings();
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObjectLoaded;
AssociatedObject.Unloaded += AssociatedObjectUnloaded;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Loaded -= AssociatedObjectLoaded;
AssociatedObject.Unloaded -= AssociatedObjectUnloaded;
}
private void AssociatedObjectUnloaded(object sender, RoutedEventArgs e)
{
SetSettings();
}
void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
{
var settings = GridSettings;
var columns = AssociatedObject.Columns.ToList();
var colCount = columns.Count;
foreach (var column in columns)
{
var key = column.Header.ToString();
if (settings.GridDisplayIndexList.ContainsKey(key))
{
//manchmal wird -1 als index abgespeichert
var index = settings.GridDisplayIndexList[key];
if(index > 0 && index < colCount)
column.DisplayIndex = index;
}
if (settings.GridColumnVisibilityList.ContainsKey(key))
{
column.Visibility = settings.GridColumnVisibilityList[key];
}
if (settings.GridColumnWidthList.ContainsKey(key))
{
column.Width = new DataGridLength(settings.GridColumnWidthList[key]);
}
}
}
private void SetSettings()
{
var settings = GridSettings;
foreach (var column in AssociatedObject.Columns)
{
var key = column.Header.ToString();
var displayindex = column.DisplayIndex;
var visibility = column.Visibility;
var width = column.ActualWidth;
if (settings.GridDisplayIndexList.ContainsKey(key))
{
settings.GridDisplayIndexList[key] = displayindex;
}
else
{
settings.GridDisplayIndexList.Add(key, displayindex);
}
if (settings.GridColumnVisibilityList.ContainsKey(key))
{
settings.GridColumnVisibilityList[key] = visibility;
}
else
{
settings.GridColumnVisibilityList.Add(key, visibility);
}
if (settings.GridColumnWidthList.ContainsKey(key))
{
settings.GridColumnWidthList[key] = width;
}
else
{
settings.GridColumnWidthList.Add(key, width);
}
}
}
}
Thanks for the help in advance. First time posting here.
I have included a bit of sample code. I would like to dynamically build a ContextMenu based on these custom objects(ObservableCollection). I can bind the ContextMenu to the first level of Team, but can you also bind a second level "ContextMenu? / MenuItem?" for the territories. I need to see the territories in a team when the team is highlighted.
My Team Object
class Team
{
private int _TeamProperty1 = 0;
private int _TeamProperty2 = 0;
ObservableCollection<Territory> _Territories = new ObservableCollection<Territory>();
public Team()
{
}
public ObservableCollection<Territory> Territories
{
get { return _Territories; }
set { _Territories = value; }
}
public int TeamProperty1
{
get { return _TeamProperty1; }
set { _TeamProperty1 = value; }
}
public int TeamProperty2
{
get { return _TeamProperty2; }
set { _TeamProperty2 = value; }
}
}
My Territory Object
class Territory
{
private int _TerritoryProperty1 = 0;
public int TerritoryProperty1
{
get { return _TerritoryProperty1; }
set { _TerritoryProperty1 = value; }
}
public void Method1()
{
//Do Some Work
}
}
Application
class MyApplication
{
ObservableCollection<Team> _Teams = new ObservableCollection<Team>();
ContextMenu _TeritorySwitcher = new ContextMenu();
public MyApplication()
{
AddTeam()
}
public void AddTeam()
{
Team _Team1 = new Team();
_Team1.Territories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Territories_CollectionChanged);
_Teams.Add(_Team1);
Team _Team2 = new Team();
_Team2.Territories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Territories_CollectionChanged);
_Teams.Add(_Team2);
Team _Team3 = new Team();
_Team3.Territories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Territories_CollectionChanged);
_Teams.Add(_Team3);
foreach (Team t in _Teams)
{
t.Territories.Add(new Territory());
t.Territories.Add(new Territory());
t.Territories.Add(new Territory());
t.Territories.Add(new Territory());
}
}
void Territories_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
ObservableCollection<Team> _TeamsSort = new ObservableCollection<Team>(_Teams.OrderBy(tm => tm.TeamProperty1));
_TeritorySwitcher.ItemsSource = _TeamsSort;
_TeritorySwitcher.DisplayMemberPath = "TeamProperty2";
}
}
Now my ContextMenu shows the teams (3 of them), but I can't figure out how to also show the Territories (There should be 4 in each team)
Ok, I figured it out. Thanks for the direction. Here is the new MyApplication Class. In the sample I don't have any data but you can fill that in if you need to see this work. It's just a sample framework.
class MyApplication
{
ObservableCollection<Team> _Teams = new ObservableCollection<Team>();
ContextMenu _TeritorySwitcher = new ContextMenu();
public MyApplication()
{
}
public void AddTeam()
{
_Teams.Add(new Team());
_Teams.Add(new Team());
_Teams.Add(new Team());
_Teams.Add(new Team());
foreach (Team t in _Teams)
{
t.Territories.Add(new Territory());
t.Territories.Add(new Territory());
t.Territories.Add(new Territory());
}
SetContextMenu();
}
private void SetContextMenu()
{
HierarchicalDataTemplate _hdtTerritories = new HierarchicalDataTemplate();
_hdtTerritories.DataType = typeof(Territory);
HierarchicalDataTemplate _hdtTeams = new HierarchicalDataTemplate();
_hdtTeams.DataType = typeof(Team);
FrameworkElementFactory _TeamFactory = new FrameworkElementFactory(typeof(TreeViewItem));
_TeamFactory.Name = "txtTeamInfo";
_TeamFactory.SetBinding(TreeViewItem.HeaderProperty, new Binding("TeamProperty1"));
FrameworkElementFactory _TerritoryFactory = new FrameworkElementFactory(typeof(TreeViewItem));
_TerritoryFactory.Name = "txtTerritoryInfo";
_TerritoryFactory.SetBinding(TreeViewItem.HeaderProperty, new Binding("TerritoryProperty1"));
_hdtTeams.ItemsSource = new Binding("Territories");
_hdtTeams.VisualTree = _TeamFactory;
_hdtTerritories.VisualTree = _TerritoryFactory;
_hdtTeams.ItemTemplate = _hdtTerritories;
_TeritorySwitcher.ItemTemplate = _hdtTeams;
_TeritorySwitcher.ItemsSource = this._Teams;
}
}