ObservableCollection as base Class c# - c#

I have a class that is derived from ObservableCollection as listed below
public class Accounts : ObservableCollection<Account>
{
public Accounts(){}
// some code
// mode plus plus code
}
at other place i have
Accounts.CollectionChanged += Accounts_CollectionChanged;
Now whenever i change/update or add any thing in Account , the below event fires and things are fine so far.
void Accounts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
MessageBox.Show("Add");
break;
case NotifyCollectionChangedAction.Remove:
MessageBox.Show("Remove");
break;
case NotifyCollectionChangedAction.Replace:
MessageBox.Show("Replace");
break;
case NotifyCollectionChangedAction.Reset:
MessageBox.Show("Reset");
break;
}
}
However my problem (its painful) is the First event it gives me is 'Reset' always, no matter what i do (update any value in account or add another account). Then if there are 2 items in collection, 'Add' event will fire two times but Replace event DOESN'T Fire.
Second problem i am having is (kind of first problem) if i add any thing to the collection and if there are 4 items already in the collection it generates 'Add' event 5 times (first 4 times for existed items and 5th one for new item) and i am not sure what am if doing wrong or i don't know how to fix it. Any idea what needs to be done to handle this?
Any help will be appreciated

Related

Is this an alright method for buttons?

I'm practicing with buttons in Unity and I'm trying to figure out how I can assign different methods to a button without using the OnClick thing in the inspector so I came up with this.
public class UIButtons : MonoBehaviour
{
void Start()
{
var buttons = FindObjectsOfType<Button>(); //I should probably have this outside of this method
foreach (Button button in buttons)
{
button.onClick.AddListener(() => ButtonPressed(button));
}
}
void ButtonPressed(Button button)
{
switch (button.name)
{
case "MMPlayButton": //The main menu play button
Debug.Log("Play button pressed");
break;
case "PlayButton":
Debug.Log("Play button pressed");
break;
case "SettingsButton":
Debug.Log("Settings button pressed");
break;
case "QuitButton":
Debug.Log("Quit button pressed");
break;
default:
Debug.LogWarning("Button doesn't have a case: " + button.name);
//could do some kind of pop up message saying the button pressed isn't available or something
break;
}
}
}
I know this can work, however, I'd imagine this is a horrible way to do things because it's using the name so if I were to change the name or make a typo it breaks, or an issue I did encounter was if buttons have the same name, and if I add more buttons I'd have to add more cases and then it would probably turn out to be a giant mess.
I could be wrong though and maybe this is an alright idea, but I doubt it so looking for some help with this.
You can simplify this by using inheritance. Create a base class for all of your buttons to use, ie. UIButtonBase that has the OnButtonPressed virtual method. Then create specific buttons that inherit this base class and override the OnButtonPressed method.
Base Class
public class UIButtonBase: MonoBehaviour
{
protected virtual void Awake()
{
var button = GetComponent<Button>();
if (button)
{
button.onClick.AddListener(() => OnButtonPressed());
}
else
{
Debug.Log(name + " does not have a Button component!");
}
}
protected virtual void OnButtonPressed()
{
Debug.Log("UIButtonBase::OnButtonPressed()");
}
}
Specific implementation of a button
public class SettingsButton : UIButtonBase
{
protected override void OnButtonPressed()
{
Debug.Log("SettingsButton::OnButtonPressed()");
// If you want the base functionality as well, add..
//
base.OnButtonPressed();
}
}
For setup, create a button and add this script to it. You may need to change the GetComponent in Awake (UIButtonBase) to GetComponentInParent or GetComponentInChildren, depending on your gameobjects hierarchy. You could also expose the Button component in the UIButtonBase script and use that reference.
I know this won't be a good answer but if I were you, I would make different files for different buttons. Like SettingButton.cs, PlayButton.cs etc.
This approach will not add a huge amount of burden to your code but as the functionalities of your buttons increase, this approach will greatly help to keep your code organized.

SystemMediaControls.ButtonPressed event fires twice

I want to add a media player control to SystemMediaControls. But, I have an issue here. When you pressed it, it occurs twice. Please see code below:
using Windows.Media;
using . . .
public class Main{
public static SystemMediaTransportControls systemMediaControls;
public Main(){
this.InitializeComponent();
systemMediaControls = SystemMediaTransportControls.GetForCurrentView();
int num = 0;
systemMediaControls.ButtonPressed += async (SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs e) =>
{
num++;
Debug.WriteLine($"Event number: {num}");
};
}
}
I proved it with debug logs, and the debug logs are:
Event number: 1
Event number: 1
Event number: 2
Event number: 2
Event number: 3
Event number: 3
I have no idea where's the problem is.
This is my fault. I put event on MainPage main function. The mistake is, I call MainPage more than once in the App.cs. For example:
void LaunchApp() {
new MainPage();
...
rootFrame.Navigate(typeof(MainPage));
}
So it initializes twice. That's why the event also fires twice. I have resolved my issue.
SystemMediaControls.ButtonPressed event fires twice
I have tested with official code sample here. Unfortunately, we can't reproduce this problem, Derive official tutorial, if you want to custom SystemMediaTransportControls, we need to sync playback status To MediaPlayerState at fist. and control the media player in button pressed event.
switch (mediaPlayer.PlaybackSession.PlaybackState)
{
case MediaPlaybackState.None:
systemMediaControls.PlaybackStatus = MediaPlaybackStatus.Closed;
break;
case MediaPlaybackState.Opening:
// This state is when new media is being loaded to the MediaPlayer [ie.
// Source]. For this sample the design is to maintain the previous playing/pause
// state before the new media is being loaded. So we'll leave the PlaybackStatus alone
// during loading. This keeps the system UI from flickering between displaying a "Play"
// vs "Pause" software button during the transition to a new media item.
break;
case MediaPlaybackState.Buffering:
// No updates in MediaPlaybackStatus necessary--buffering is just
// a transitional state where the system is still working to get
// media to start or to continue playing.
break;
case MediaPlaybackState.Paused:
if (mediaPlayer.PlaybackSession.Position == TimeSpan.Zero)
systemMediaControls.PlaybackStatus = MediaPlaybackStatus.Stopped;
else
systemMediaControls.PlaybackStatus = MediaPlaybackStatus.Paused;
break;
case MediaPlaybackState.Playing:
systemMediaControls.PlaybackStatus = MediaPlaybackStatus.Playing;
break;
}
For more detail please refer Manual control of the System Media Transport Controls

Create default childs to node in umbraco

I'm trying to find out how to force node to create only one node child of other type ?
I have 'hotel' node and i want to add one 'rooms' node and one 'facilities' node ('rooms' create 'room' and 'facilities' create 'facility')
by default when i will create hotel the system will create this 2 folders or to force him that he can create only one each
I prefer to do it with the management system (if possible) but code behind be good also !
Thanks in advance for all helpers!
As far as I am concerned, I do not know a way to achieve this by means of the Umbraco backoffice.
However, you can use the ContentService Events in order to cancel the creation of that particular page if it has been already created. The ContentServiceSaving method will fire up each time that you try to create a node in the CMS.
public class ContentServiceEventsController : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentService.Saving += ContentServiceSaving;
}
private void ContentServiceSaving(IContentService sender, SaveEventArgs<IContent> e)
{
switch (e.Entity.ContentType.Alias)
{
case "RoomsDocumentTypeAlias":
case "FacilitiesDocumentTypeAlias":
// Do your logic to detect if your Hotel node "Hilton eilat queen of sheba"
// already contains either a Rooms node or a Facilities node underneath.
// If so, cancel the creation of the event of a new one.
e.Cancel = true;
break;
default:
break;
}
}

Listening event outside MainPage class calling method multiple times on button click event (repetetively)

I have a situation where I have to manage the button click event outside MainPage class (suppose in Class B). Here is the code that I'm using:
namespace TEST
{
public partial class MainPage: UserControl
{
public event Action simpleEvent;
public MainPage()
{
}
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch (comboBox1.SelectedItem as string)
{
case "UInt8":
B obj4 = new B(this, fileContent, "UInt8");
break;
case "UInt16":
B obj1 = new B(this, fileContent, "UInt16");
break;
case "UInt32":
B obj2 = new B(this, fileContent, "UInt32");
break;
case "UInt64":
B obj3 = new B(this, fileContent, "UInt64");
goto
default;
default:
MessageBox.Show("check");
break;
}
}
private void ButtonClick_EVENT(object sender, RoutedEventArgs e)
{
// I try to listen outside the class this way.
if (simpleEvent != null)
simpleEvent();
}
}
Class B
{
public B(MainPage Obj, byte[] fileContent, string type)
{
switch (type = Obj.comboBox1.SelectedItem as string)
{
case "UInt8":
{
//do something
break;
}
case "UInt16":
{
//do something
break;
}
case "UInt32":
{
//do something
break;
}
case "UInt64":
{
//do something
goto
default;
}
default:
{
break;
}
}
Obj.simpleEvent += () = > MyMethod(Obj);
}
public void MyMethod(MainPage Obj)
{
// This MessageBox repeats 2 times on second time button click
// and 3 times on 3rd button click .
// It should be called once even on second/third/fourth etc. button clicks.
MessageBox.Show("Repetition check");
}
}
}
The problem is my method is called repetitively. For example, when I click the button the first time it will be called only once (which is good). and if I click the button again the message box pop-up comes up 2 times and again pop-ups 3 times on 3rd attempt.
What I want is to pop-up this message box only once on the click (even if I keep on clicking on the button one after the other click).
EDIT: The new updated code is the actual situation i was trying to make it short so last time i didn't include to much code (because i was not suspecting that part).
What i am trying to do is :
I have to select 1 data type among 4 given data type at run time (uint64/32/16/8)(which will be data type for reading a file ("fileContent" in constructor call), but it's not related to question i asked, so leaving too much discussion on it).After selecting that data type i click the button to display something. (so each time i first i select "data type" from combo box and then i press button to display some data corresponding to that data type then i again select another data type from combo box and then again i press "button" but this time it pop-ups message 2 times, and when i repeat the same 3rd time it pop-ups messagebox 3times).
Suppose first i selected "uint64" in combo box at run time (in the first attempt) and then i click button to display messagebox it will pop-up the message box once.Now without closing the application my second selection to combo box is on uint32 (On second attempt) and again i click to "button" this time this message box is popped 2 times. I don't know why? and on third attempt it pop-ups 3 times.
(1) Why message box repeats ?
Thanks for the help in advance, I really wanna know the reason for it, not able to understand yet.
You're creating a new B object every time your combobox is changed. That adds a new handler every single time, without ever removing the previous handlers. You need to either unsubscribe the old handler when you go to add a new one, or only ever add one handler and simply modify the data that it relies on so that that handler acts appropriately when it fires.

Fill a combo box by selecting item in ListView

Im trying to fill combobox from one of two arraylist, on changing selection in listview with method listView1_SelectedIndexChanged.
The problem is it works fine the first time, but the second time I get the following error: "Object reference not set to an instance of an object."
The error is probably happening here: string pr = listView1.FocusedItem.Text;
Please help.
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
ArrayList Profesor1 = new ArrayList();
Profesor1.Add("Kolegij 1 profesor 1");
Profesor1.Add("Kolegij 2 profesor 1");
ArrayList Profesor2 = new ArrayList();
Profesor2.Add("Kolegij 1 profesor 2");
Profesor2.Add("Kolegij 2 profesor 2");
string pr = listView1.FocusedItem.Text; //posible prob
switch (pr)
{
case "Profesor 1": comboBox1.DataSource = Profesor1;
break;
case "Profesor 2": comboBox1.DataSource = Profesor2;
break;
}
}
Is there something else going on in your example affecting the listView1 item? I've mocked up a small clone of your question and I can't seem to replicate the error:
I'm using your code for the event handler, and I'm populating the listView1 thusly:
listView1.Items.Add("Profesor 1");
listView1.Items.Add("Profesor 2");
It sounds like you're causing the listView1_SelectedIndexChanged handler to be fired in the background.
As a slight aside, your array lists aren't going to change, you probably don't want to keep your ArrayList creation in your event handler and keep recreating them each time (they don't seem to have any dynamic information in). particularly as that handler will often be called twice once, for the deselection, and again for a selection.
On that last point, it's also worth having a look at the ItemSelectionChanged event, which could be used to help your initial problem, as it comes with ListViewItemSelectionChangedEventArgs which contain the property IsSelected, which you could use to verify that you have an object selected.
e.g:
private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
if (e.IsSelected)
{
// Your code here.
// e.Item...
}
}

Categories

Resources