I have 4 radio buttons that every one of them shows a different list in a combobox that attached to them. The radio button should be available only after pressing a some button. I want one of the radio button to be chosen and than the last row on the combo list to be chosen automatically.
MAINWINDOWS.XAML
<!--RadioButtons-->
<RadioButton x:Name="RadioButtonA" GroupName="Button" Content="A" Margin="0,5,0,0" Grid.Column="0" Click="RadioButtonA_Click" />
<RadioButton x:Name="RadioButtonB" GroupName="Button" Content="B" Margin="0,20,0,0" Grid.Column="0" Click="RadioButtonB_Click"/>
<RadioButton x:Name="RadioButtonC" GroupName="Button" Content="C" Margin="0,35,0,0" Grid.Column="0" Click="RadioButtonC_Click"/>
<RadioButton x:Name="RadioButtonD" GroupName="Button" Content="D" Margin="0,50,0,0" Grid.Column="0" Click="RadioButtonD_Click"/>
<!--ComboBox-->
<ComboBox
x:Name="ComboBox"
IsEnabled="false"
Grid.Column="1"
Width="240"
Height="30"
VerticalAlignment="Top" Margin="0,8,0,0"
SelectionChanged="ComboBoxSelectionChanged" >
</ComboBox>
ViewModel: Example for one of the radiobuttons
private void RadioButtonA_Click(object sender, RoutedEventArgs e)
{
IdComboBox.SelectedValue = string.Empty;
IdComboBox.IsEnabled= true;
IdComboBox.Items = AList;
currentIdentifier = Identifier.A;
}
You mentioned "ViewModel", but you actually don't use MVVM.
Using event handlers to set state of many related controls is a doomed way - because complexity increases in proportion to the square of the amount of controls. You have to use MVVM, the approach when properties of controls are projected to a property of a model. Then you can use triggers to set controls state depending on the model property values. Or, if you consider triggers too verbose, you can use QuickConverter, this library helps to simplify code.
Even if you don't like/cannot use any of them, please, use triggers to set state of comboboxes.
Related
I have a ListView with a collection as ItemsSource.
<ListView x:Name="lvBT" Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}"
ItemsSource="{x:Bind ViewModel.CurrentPoste.TableauxBT}" Margin="0,0,0,12"
IsEnabled="{x:Bind ViewModel.CurrentPoste.BtEdition, Mode=TwoWay}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:BT">
[...]
<TextBox x:Name="tbNumSerieBT" HorizontalAlignment="Stretch" Margin="12,32,16,0" Text="{x:Bind NumSerie, Mode=TwoWay}" VerticalAlignment="Top" Grid.Column="3" FontSize="16" Grid.ColumnSpan="2"/>
<Button x:Name="bScannerBT" Grid.Column="5" HorizontalAlignment="Stretch" Margin="12,32,15,0" VerticalAlignment="Top" Content="Scanner tabeau BT" FontSize="14" Click="BScannerBT_Click"/>
[...]
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
tableauxBT is representing a collection of BT objects and for each object in that collection I'm creating a DataTemplate, like basic data binding.
When I click on the Button in that template I'm scanning a barcode with a BarcodeScanner and want to put the return value in the TextBox field.
For each button of each different BT item I want to scan a different barcode but the problem is that I don't know how to get the index of the Button that was clicked to put the value in the right TextBox.
So how can I do to get the index of the clicked Button to put the value in the TextBox at the same index ?
You can get the index of the clicked button using the "BScannerBT_Click" method.
public BScannerBT_Click(object sender, EventArgs e)
{
var myClickedButton = (Button)sender; //this object hold all information you need.
//You can reach the button's dataContext and change the value you want to.
var buttonDataContext = myClickedButton.DataContext.
//now you have the ViewModel (buttonDataContext) associated with the 'NumSerie'
}
I hope it helps you.
I'm quite new to c# wpf and have a problem.
I have used the answer from this post to duplicate a Grid control. The grid control contains a button. It looks like it is being duplicated correctly.
When the original control's button is pressed, the click event is handled which calls a method in the window's code.
When the copy of the control's button is pressed, the click event is not fired and the method is not called. This is confusing me as I want it to call that same method.
Maybe the event handling data is not being copied properly? Is there a way around this?
Both the origional grid and copied grid (containing the buttons) are children of another grid.
Edit:
This is the xaml for the origional grid which contains a button:
<Grid Name="TempTab" DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="5,5,5,0">
<Rectangle Fill="Black" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke ="White" Margin="0,0,-2,0">
</Rectangle>
<Grid>
<DockPanel LastChildFill="False">
<TextBlock Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="3,0,3,3">Some Text</TextBlock>
<Button Width="50" BorderBrush="{x:Null}" Foreground="{x:Null}" BorderThickness="0" Margin="3,0,0,0" Click="tabdowntest">
<Button.Background>
<ImageBrush ImageSource="TopMenuBar_Close.png" Stretch="Uniform"/>
</Button.Background>
</Button>
</DockPanel>
</Grid>
</Grid>
This grid is a child of a DockPanel with name 'TabsDock'.
It is being copied with the following code:
string gridXaml = XamlWriter.Save(TempTab);
StringReader stringReader = new StringReader(gridXaml);
XmlReader xmlReader = XmlReader.Create(stringReader);
Grid newTab = (Grid)XamlReader.Load(xmlReader);
TabsDock.Children.Add(newTab);
This is the code for the 'Click' event handler which should be called when the either the origional or the copied button's are pressed. But it is only called for the origional:
private void tabdowntest(object sender, MouseButtonEventArgs e)
{
Console.WriteLine("Button Pressed");
}
The bindigs are not set, you need to set them (comment in the orig post):
To be clear, this is only half the solution (as it stood back in 08). This will cause bindings to be evaluated and the results be serialized. If you wish to preserve bindings (as the question asked) you must either add a ExpressionConverter to the Binding type at runtime (see the second part of my question for the relevant link) or see my own answer below for how to do it in 4.0.
I am learning WPF and have spent waaaay too much time trying to solve this simple task.
My goal is to add two RibbonComboBoxes to a ribbon control. One for Categories, and another for Subcategories. Whenever the user changes the Category, I would like to have the Subcategories combo box update to show the subcategories for the current category.
XAML:
<RibbonTab Header="Home">
<RibbonGroup Header="Category">
<RibbonComboBox Label="Category:" HorizontalContentAlignment="Left" SelectionBoxWidth="250" Focusable="False">
<RibbonGallery Name="galCategory" DisplayMemberPath="Text" SelectedValuePath="Value">
</RibbonGallery>
</RibbonComboBox>
<RibbonComboBox Label="Subcategory:" HorizontalContentAlignment="Left" SelectionBoxWidth="250">
<RibbonGallery Name="galSubcategory" DisplayMemberPath="Text" SelectedValuePath="Value">
</RibbonGallery>
</RibbonComboBox>
</RibbonGroup>
</RibbonTab>
I found that only by adding the RibbonGallery element, I can access methods that allow me to populate the combo box. However, while my data shows in the list, the items cannot be selected by the user. (Clicking items in the list has no effect whatsoever.)
Can anyone tell me how to populate these controls?
Note: Bonus points to anyone who can tell me how to make the two combo boxes align up to each other regardless of the length of text in the label!
Add a RibbonGalleryCategory control inside RibbonGallery and then populate it. Add a selection change event listener to RibbonGallery:
XAML:
<RibbonComboBox Label="Category:" Name="rcmbCategory" SelectionBoxWidth="100" Height="20" HorizontalContentAlignment="Center">
<RibbonGallery Name="galCategory" DisplayMemberPath="Text" SelectedValuePath="Value" SelectionChanged="RibbonGallery_SelectionChanged">
<RibbonGalleryCategory Name="rgcCategory"/>
</RibbonGallery>
</RibbonComboBox>
.CS:
public MainWindow()
{
InitializeComponent();
for(int i=0;i<=10;i++)
rgcCategory.Items.Add(i);
}
private void RibbonGallery_SelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
MessageBox.Show(rcmbCategory.SelectionBoxItem.ToString());
}
Refer to CodeProject: RibbonComboBox for more information.
I'm trying to programatically create a button flyout, within my XAML I have:
<Page.Resources>
<Button x:Key="LaunchFlyout" Content="LAUNCH">
<Button.Flyout>
<Flyout Placement="Top">
<Grid Width="200" Height="200">
<StackPanel>
<Rectangle Fill="Red" Width="100" Height="100" />
<Rectangle Fill="Green" Width="100" Height="100" />
</StackPanel>
</Grid>
</Flyout>
</Button.Flyout>
</Button>
</Page.Resources>
Nested within grids I have:
<Grid x:Name="launchBtn_grid" Grid.Column="1">
</Grid>
And then in my code within the Page_Loaded method I have:
bool hasContainer = localSettings.Containers.ContainsKey("appStatus");
if (!hasContainer) {
Button button = (Button)this.Resources["LaunchFlyout"];
launchBtn_grid.Children.Add(button);
}
else {
Button button = new Button();
button.Content = "LAUNCH";
button.Click += launch_btn_Click;
launchBtn_grid.Children.Add(button);
}
When I debug this, it reaches the IF statement and reaches this line launchBtn_grid.Children.Add(button); and then I get this error Element is already the child of another element.
Does anyone understand why? I have already looked and they dont already exist so I don't understand why it is giving me this error. Does anyone know what I am doing wrong?
I'm not sure in what context/use case your are doing that, but it feels weird to me to have an actual control as a Resource (not a DataTemplate, Style, etc).
If you only want to have 1 button of the 2 different template, why not switch Visibility on the 2 instead of loading controls from your code behind ?
Going forward with the idea, just add both buttons in the Grid within your XAML and switch their Visibility according to the setting you read.
There is a BooleanToVisibilityConverter within the framework to help you with this.
I am having an issue with my button event not occuring
Basically I have cart items that are listed in the listbox. When the delete button is clicked then the item is deleted from the list box.
I tried debugging, but it seems to not even call the method for when the button is clicked.
In my ticketscreen.xaml file I specify my button in the template:
<DataTemplate x:Key="TicketTemplate">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Height="50">
...
<Button Name="Remove" Width="35" Height="35"
FontFamily="Resources/#charlemagnestd-regular.otf" FontSize="24"
Click="removeCartItem" Grid.Column="5"
MouseMove="Remove_MouseMove">X</Button>
...
</StackPanel>
</DataTemplate>
My List box is the following:
<ListBox Name="TicketItems" ItemsSource="{Binding}"
ItemTemplate="{StaticResource TicketTemplate}"
Grid.Row="3" Grid.ColumnSpan="6" Background="Transparent"
BorderBrush="Transparent" IsHitTestVisible="False">
</ListBox>
My method removeCartItem is in the ticketscreen.xaml.cs:
private void removeCartItem(object sender, RoutedEventArgs e)
{
Console.WriteLine("TestingCartRemove");
}
Am I missing something obvious?
Thx in adv! :)
Edit:
There seems to be something infront of it... maybe the listbox? How do I make it so that I am not clicking the ListBox, but I can click on things within the Stackpanel, which are contents of the list box.
IsHitTestVisible="False" for the ListBox is disabling the click event for the Button. It makes all content within the ListBox invisible to hit-test as well.
Are you sure is not firing? Maybe you haven't seen the output in Visual Studio Output Window. Try to call a MessageBox.Show("Test"); instead.
You have a listbox control, which leads me to believe that this is not a console application. Therefore, Console.WriteLine() will not show you anything. Try MessageBox.Show() instead.