Given this property that changes the Selected File every time I click an item I my listBox:
public IMediaFile SelectedPlayListFile
{
get { return this.selectedPlayListFile; }
set { this.RaiseAndSetIfChanged(ref selectedPlayListFile, value);
}
and called later with:
var file = this.SelectedPlayListFile;
How could i set the property without the RaiseAndSetIfChanged event? I need to change the SelectedPlayListFile programmatically and let the UI reflects that change too. (No more clicking)
So the SOLUTION was SO obvious...
this.SelectedPlayListFile = filesCollView.CurrentItem as IMediaFile;
Thank you for this newbie question.
Related
Background information:
We have a UserControl called Sensor.
Sensor has a property called SlaveSensor.
The type of the property SlaveSensor is Sensor.
public Sensor SlaveSensor;
{
get
{
return _slaveSensor;
}
set
{
//Some more code for checking various stuff...
_slaveSensor; = value;
}
}
As you can see, the type of the property is the same as the UserControl itself.
The property SlaveSensor is normally set via the properties window during design time.
Visual Studio automatically provides the editor as a drop-down list, from which one can select from all available Sensors on the form.
My question is:
How can I make the drop-down list start at a specified instance in the list,
to make it quicker to find the right Sensor to set for the property?
The name of the Sensor to set as the property is always nearly the same as the name of the Sensor for which the property is being set.
So if e.g. the drop-down list would simply auto scroll to the index in the list that has the name of the Sensor for which the property is being set,
I have achieved my goal.
What do I have so far:
I assume that I need to implement a custom property editor.
I might actually be able to create one with a drop-down list, and fill this with strings,
but the existing is OK as it is, I just need to tell it to drop-down to a certain index when clicked.
Thanks for any help in advance!
I'd try this.
string text = "SomeText";
var item = dropdown.Items.FindByText(text);
if(item!= null)
item.Selected = true;
Or by value:
string value = "SomeValue";
var item = dropdown.Items.FindByValue(value);
if (item != null)
item.Selected = true;
Taken from top answer here
I have a combobox bound to an Enum. When I click on a new value in my combobox, I'm generating a message to an attached device and getting a response back. I want to file whatever value is received back.
My regular-old bound property looks like this:
private Enum enumValue;
public Enum EnumValue
{
get => enumValue;
set
{
if (enumValue != value)
{
enumValue = value;
sendToDevice();
}
}
}
My update from device looks like this:
public void SetValueFromDevice(string valueFromDevice)
{
enumValue = (Enum)Enum.Parse(EnumType, valueFromDevice);
RaisePropertyChanged(nameof(EnumValue));
}
Note that I'm setting the private variable enumValue directly because I don't want to trigger another outgoing message to my device if I don't need to.
Here's the situation: Let's say I have an enum that looks like this:
public enum Sources
{
Off,
Low,
Mid,
Hi
}
The firmware I've written doesn't like the value of low on certain versions on the device. Instead, it'll reply back with whatever the current value is. I want to file that back to the combo box instead of showing the incorrect value to the user.
Now, what seems to happen is after I click on the combobox item, it sends a message to my device, gets the response, and then files it back appropriately. I can step through and see the combobox doing the "get" after I call RaisePropertyChanged, but it doesn't seem to be updating the selected item at all.
I can call SetValueFromDevice and that always works, so it seems like it's the UI acting up.
I even attempted to totally force it with
control.DropDownClosed += new EventHandler(SourceBox_DropDownClosed);
....
private void SourceBox_DropDownClosed(object sender, EventArgs e)
{
ComboBox box = sender as ComboBox;
box.GetBindingExpression(ComboBox.SelectedItemProperty).UpdateTarget();
}
...and that did nothing.
What am I doing wrong here? Is there any way to set the item of the combobox during the item selection interaction?
Figured it out: I needed to make my sendToDevice() call asyncronous, because I'd be triggering the RaisePropertyChanged twice in the same process, and it'd only "see" the first one.
App.Current.Dispatcher.InvokeAsync(() => sendToDevice());
I have a WPF application with multiple tabs. Under each tab, a user can change some settings (using CheckBoxes, TextBoxes, etc) and then the user must click the "Update" button in order to save those settings. Everything works fine but one of requirements is to alert the user if he tries to switch to other tab without clicking the "Update" button.
So I'm trying to use the
TabItem_LostFocus
event handler to achieve it but this event is triggered every time I click on something within the tab. I guess I can patch this issue by placing
e.Handled = true
for every control I have but this doesn't sound like an elegant solution (especially when I don't have click event handlers for everything under my tabs). Is there some other way to determine when you are switching away from the current tab?
Thank you
To achieve your requirement, you just need to data bind to the TabControl.SelectedIndex or the TabControl.SelectedItem properties:
<TabControl ItemsSource="{Binding TabItemCollection}"
SelectedItem="{Binding SelectedTabItem}" />
Then in your view model or code behind:
private YourDataType selectedItem;
public YourDataType SelectedItem
{
get { return selectedItem; }
set
{
// selectedItem represents the previous TabItem
// value represents the new TabItem
selectedItem = value;
}
}
You can bind to the IsSelected property of each TabItem.. and then do your checking inside the setter
<TabControl>
<TabItem IsSelected="{Binding TabItem1IsSelected}"/>
</TabControl>
Property:
public bool TabItem1IsSelected
{
get { return _tabItem1IsSelected; }
set
{
if (_tabItem1IsSelected)
{
if (!value)
{
// Check to see if user has updated
if (!userUpdated)
{
value = true;
}
}
}
_tabItem1IsSelected = value;
RaisePropertyChanged();
}
}
Is is possible to make a binding in WPF whereas the source and target are different properties.
A la something like
Binding="{Binding Source=MySourceProperty, Target=MyTargetProperty}"
As requested an explanation of what I need to do:
The program among other things allows editing of properties that are part of a primary key in the database. If the property just gets changed, then this will either not update the DB value or create a duplicate, depending on how I handle saving the object. A different target would allow this to work (by explicitly specifying what to update by using the 'old' value).
A Binding defined in XAML is always targeting the object and property on which it's defined.
If you define the Binding in code, you can/must specify the source and target explicitly. This is, essentially, how the Binding class works:
Binding binding = new Binding("SourceProperty"); // Sets up the source property
myBinding.Source = mySourceObject; // sets up the source object
targetProperty.SetBinding(TargetType.TargetDepProperty, binding); // This sets the target object/binding
The XAML markup extension for a binding takes care of setting up the target side of the equation automatically, so it's always the object on which you define the binding.
I'll try to answer WHAT you need instead of asked incorrect HOW
"If the property just gets changed, then this will either not update
the DB value or create a duplicate"
In your property setter you should check set { if (this.someMember != value) if the typed in value is has changed:
public event PropertyChangedEventHandler PropertyChanged;
private string someMember;
public int SomeProperty
{
get
{ return this.someMember; }
set
{
if (this.someMember != value)
{
someMember = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("SomeProperty"));
}
}
}
As aside-note (or off-topic),
you might find useful the codeproject DataContext in WPF article in its last Download the source code has a sample when updates of one VisualModel's property is reflected (synchronized with updates in the other VM's property)
Immediately after launch:
The text typed in the 1st textbox is reflected in the 2nd textbox and vice versa, the text typed in the 2nd textbox is reflected in the 1st.
The text typed in the 3d textbox is reflected in the 4th textbox (and in textblock content at bottom) and vice versa, the text typed in the 4th textbox is reflected in the 3d (and in textblock content at bottom) .
Note that the download is DataCotext Inner Objects.zip which is unzipped into directory and solution with name Bindingtoclassesstate
In the set of the public property you have access to the old value
key is the old value
value is the proposed value from the binding
you can reject the value that comes from the binding
private string key;
public string Key
{
get { return key; }
set
{
if (key == value) return;
// try data update
bool success = updateDB();
if (success) key = value; // only update if success
}
}
I would combine the above with validation to notify the user if a value was invalid.
Validation Class
I have a textbox and have an onlostfocus event on it.
Inside the lostfocus method, is there a way I can determine if the user has actually changed the value in it?
i.e how do i get hold of any previous value in it?
Thanks
As with just about everything else in WPF, this is easier if you use data binding.
Bind the text box to a class property. By default, bindings update the source when the bound control loses focus, so you don't have to muck around with the LostFocus event. You then have access to both the new value and the value that the user entered in the property setter.
In the XAML it looks like this:
<TextBox Text="{Binding MyProperty, Mode=TwoWay}"/>
In the class it looks like this:
private string _MyProperty;
public string MyProperty
{
get { return _MyProperty; }
set
{
// at this point, value contains what the user just typed, and
// _MyProperty contains the property's previous value.
if (value != _MyProperty)
{
_MyProperty = value;
// assuming you've implemented INotifyPropertyChanged in the usual way...
OnPropertyChanged("MyProperty");
}
}
What comes to mind for me is a two stage approach. Handle the TextChanged event on the textbox and flag it. Then when the textbox OnLostFocus occurs you can simply check your flag to see if the text has been changed.
Here is a code snippet on how you could handle the tracking.
public class MyView
{
private bool _textChanged = false;
private String _oldValue = String.Empty;
TextChanged( ... )
{
// The user modifed the text, set our flag
_textChanged = true;
}
OnLostFocus( ... )
{
// Has the text changed?
if( _textChanged )
{
// Do work with _oldValue and the
// current value of the textbox
// Finished work save the new value as old
_oldValue = myTextBox.Text;
// Reset changed flag
_textChanged = false;
}
}
}
Store the original value somewhere. You could write a common component to store the value when it gets focus and compare the value when it loses focus. I've done this in ASP.NET and it works quite well.
Another way to solve this by databinding:
Bind the TextBox.Text to the property, that holds the inital value, but use a binding with
UpdateSourceTrigger=Explicit
Then, when the textbox loses focus, you can check the binding if source and target values differ, using this code snippet and evaluating the resulting BindingExpression:
BindingExpression be = tb.GetBindingExpression(TextBox.TextProperty);
Some more code can be found here:
http://bea.stollnitz.com/blog/?p=41