I have an WPF form with a listbox and a button on it.
I populate a listbox (tagbox) with the List and then bind this with datasource as below.
private void WeekFood_Load(object sender, EventArgs e)
{
List<string> tags = new List<string>() { "A", "B", "C"};
tagbox.DataSource = tags;
InitializeComponent();
}
Then when I click the button, I run the following code
private void GenSunday_Click(object sender, EventArgs e)
{
MessageBox.Show(tagbox.SelectedItems.Count.ToString());
}
No matter how many items are selected in the listbox it always returns 0 with tagbox.SelectedItems always being null.
I have tried populating the box by iterating the list with valuemember and displaymember however this also does not fix things.
How is this fixable.
Many thanks in advance
In WPF, please use ItemSource property for ListBox and bind the object to it.
Also call the InitializeComponent(); before assigning any data to the controls.
//MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
List<string> tags = new List<string>() { "A", "B", "C" };
tagBox.ItemsSource = tags;
}
private void button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(tagBox.SelectedItems.Count.ToString());
}
In MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListBox x:Name="tagBox" HorizontalAlignment="Left" Height="100" Margin="99,249,0,0" VerticalAlignment="Top" Width="561"/>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="99,57,0,0" VerticalAlignment="Top" Width="148" Height="34" Click="button_Click"/>
</Grid>
</Window>
Related
I'm trying to use a SourceUpdated event in ListBox, but it doesn't fire.
I have binded ObservableCollection to ItemSource of ListBox, set NotifyOnSourceUpdated = true, and binding is working correctly - after adding new item to the collection, the ListBox displays new item, but without fireing the event.
MainWindow.xaml.cs:
public partial class MainWindow:Window
{
public ObservableCollection<string> Collection { get; set; }
public MainWindow()
{
InitializeComponent();
Collection = new ObservableCollection<string>();
var custBinding = new Binding()
{
Source = Collection,
NotifyOnSourceUpdated = true
};
intList.SourceUpdated += intList_SourceUpdated;
intList.SetBinding(ItemsControl.ItemsSourceProperty, custBinding);
}
private void intList_SourceUpdated(object sender, DataTransferEventArgs e)
{
MessageBox.Show("Updated!");
}
private void btnAddInt_Click(object sender, RoutedEventArgs e)
{
var randInt = new Random().Next();
Collection.Add(randInt.ToString());
}
}
MainWindow.xaml:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button x:Name="btnAddInt" Content="Button" HorizontalAlignment="Left" Margin="41,31,0,0" VerticalAlignment="Top" Width="75" Click="btnAddInt_Click"/>
<ListBox x:Name="intList" HorizontalAlignment="Left" Height="313" Margin="160,31,0,0" VerticalAlignment="Top" Width="600"/>
</Grid>
What am I missing, that it's not working ?
Thank you for an advice.
SourceUpdated is only fired on elements that can accept input and change the databound source value directly.
https://msdn.microsoft.com/en-us/library/system.windows.data.binding.sourceupdated(v=vs.110).aspx
In this case, the listbox itself is not updating the collection, rather the collection is being updated via a button click. This has nothing to do with the listbox firing the SourceUpdated Event.
Only input elements that can accept input like a textboxes, checkboxes, radio buttons and custom controls that use those controls will be able to two-way bind and transfer their values back to the source it is bound to.
You may be looking for CollectionChanged which will fire when items are added or removed from the Collection.
https://msdn.microsoft.com/en-us/library/ms653375(v=vs.110).aspx
Collection = new ObservableCollection<string>();
Collection.CollectionChanged += (s, e) =>
{
// collection changed!
};
Hope this helps! Cheers!
I have a simple WPF app, where I have a combobox and a label, using dependency property I want to show the selected Item in label, when user select any item in the combobox, label will be changed accordingly.
Here is my code.
public event EventHandler _itemChanged;
public MainWindow()
{
List<String> items = new List<string>();
items.Add("C");
items.Add("C++");
items.Add("C#");
items.Add("Java");
items.Add("Js");
InitializeComponent();
combx.ItemsSource = items;
_itemChanged += MainWindow__itemChanged;
DependencyPropertyDescriptor dpcombx;
dpcombx =
DependencyPropertyDescriptor.FromProperty((DependencyProperty)
ComboBox.SelectedValueProperty, typeof(ComboBox));
dpcombx.AddValueChanged(dpcombx, _itemChanged);
}
void MainWindow__itemChanged(object sender, EventArgs e)
{
ComboBox cb = (ComboBox) sender;
lbl_Combx.Content = (string)cb.SelectedItem;
}
The problem is, EventHandler is not getting called. Please help me.
here is the XAML
<Window x:Class="DP.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox Name="combx"
HorizontalAlignment="Left"
Margin="57,121,0,0"
VerticalAlignment="Top"
Width="120" />
<Label Content=""
x:Name="lbl_Combx"
HorizontalAlignment="Left"
Margin="368,182,0,0"
VerticalAlignment="Top" />
</Grid>
</Window>
You need to pass the dependency object (comboBox) in the AddValueChanged instead of its property descriptor.
dpcombx.AddValueChanged(combx, _itemChanged);
Afters attemps I could tell that the FocusVisualStyle is only activated by the keyboard (tab and arrows keys).
Try to make the FocusVisualStyle to be applied after the component is loaded, it is impossible to do, There is an easy way to get around this problem?
I found this:
- focus visual not showing when navigating focus programically
- How do WPF buttons decide to show FocusVisualStyle?
- http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/99856840-f8ef-4547-9150-c4c46ec2f3df
But none shows a definite solution (without overwriting the component), and I could not write, can someone help?
I am not pretty sure I understand your issue, but I tried the example in one of the links and I was able to move focus to next component from code behind exactly as you would do using keyboard. Here is the code.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfApplication1" Loaded="OnLoaded"
>
<StackPanel Margin="10">
<TextBox Margin="10" x:Name="a" >A</TextBox>
<TextBox Margin="10" x:Name="b" >B</TextBox>
<Button Focusable="False" Click="OnClick">Move Focus</Button>
</StackPanel>
</Window>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void OnLoaded(object sender, RoutedEventArgs e) {
a.Focus();
}
private void OnClick(object sender, RoutedEventArgs e) {
var request = new TraversalRequest(FocusNavigationDirection.Next);
var elementWithFocus = FocusManager.GetFocusedElement(FocusTest) as UIElement;
if (elementWithFocus != null)
elementWithFocus.MoveFocus(request);
}
}
I'm creating a UserControl in WPF, and the UserControl works so that when the user moves mouse over the control, it's childcontrols should be removed, but I don't seem to find the Children property or anything like that..
XAML is here:
<UserControl x:Class="myTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Name="thisTextBox"
mc:Ignorable="d" d:DesignWidth="300" Height="57" MouseEnter="UserControl_MouseEnter_1" MouseLeave="UserControl_MouseLeave_1">
<TextBlock Name="TypeText" TextWrapping="NoWrap" Text="" />
</UserControl>
And in code I need to do something like this to get the TextBlock go away:
private void UserControl_MouseEnter_1(object sender, MouseEventArgs e)
{
Children.Clear(); // There is no such thing as children here!!!
}
The "child element" of the UserControl is contained in the Content property. You can set it to null in order to remove the content.
private void UserControl_MouseEnter_1(object sender, MouseEventArgs e)
{
Content = null;
}
I have this code:
private void ModifyButton_Click(object sender, RoutedEventArgs e)
{
ModifyButton.Content = "Another button name";
}
But it doesn't work. I mean, the modify button content doesn't change but the program doesn't fail or throw any exception.
I'm trying to modify the button name in order to change it's behavior (kinda Edit/Save) within the same button. Is this not possible using C#/WPF?
Thanks in advance.
EDIT:
XAML:
<Button Name="ModifyButton" Content="Modificar" Margin="5,10,0,0" Height="23" Width="120" HorizontalAlignment="Left" Click="ModifyButton_Click"></Button>
WEIRD BEHAVIOR: If I put a MessageBox.Show call after the change of the button content, then, while the message box is displayed the button dislay the new (changed) name, but after the message box is closed, then it shows it's original text.
I guess that the XAML of your UI is not bound to the value of your button. Did you check the DataBinding?
[EDIT]
Your magic information here is that you use ShowDialog(). As you already guessed, this influences your UI thread and therefore the display behavior. ShowDialog() displays the Form as a modal dialog and blocks your UI thread and therefore blocks the refresh of it. This may cause all sorts of weird behavior.
This is what i have and it works:
Window 1
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Name="ModifyButton" Content="Open Dialog" Margin="80,104,78,0" Height="23" Click="ModifyButton_Click" VerticalAlignment="Top"></Button>
</Grid>
</Window>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void ModifyButton_Click(object sender, RoutedEventArgs e)
{
Window2 win2 = new Window2();
win2.ShowDialog();
}
}
Window 2
<Window x:Class="WpfApplication1.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="300" Width="300">
<Grid>
<Button Name="ModifyButton" Content="Modificar" Margin="80,104,78,0" Height="23" Click="ModifyButton_Click" VerticalAlignment="Top"></Button>
</Grid>
</Window>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
}
private void ModifyButton_Click(object sender, RoutedEventArgs e)
{
ModifyButton.Content = "Another button name";
}
}