I have a combobox that pulls a set of options from CRM. The combobox was created in .xaml using the code:
<ComboBox x:Name="cmbTransfer" Width="200" Height="40" BorderBrush="Transparent" BorderThickness="0"
Margin="0,0,20,0" AutomationProperties.Name="Transfer State" IsTextSearchEnabled="true" FontSize="20" SelectionChanged="Transfer_Click" IsEnabled="False"/>
In C#, I set the comboboxItem.Content to "Transfer". Then I fill the comboBoxItem.Content with languages to transfer to that are pulled from CRM.
Right now, when I click the transfer dropdown, I get the following:
Transfer Dropdown UI
I want the "transfer" in the dropdown menu to not appear. Do you guys have any ideas?
#Sajeetharan: The combobox is populated using the line:
comboBoxItem.Content = (object)current.Attributes["uscb_language"].ToString();
The entity uscb_language is a list of languages from CRM
The action is fired to populate this field with the following method:
private void Transfer_Click(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (cmbTransfer.SelectedIndex != 0)
{
//UpdatePhoneCallActityWithTransferInfo("1233");
this.FireRequestAction(new RequestActionEventArgs("CTIControl", "FireEvent", "HandleTransfer"));
//await Task.Delay(20000);
}
}
Related
I'm currently making a transferring data from one listbox to another.
With WPF I have:
<Grid>
<ListBox Margin="10,29,194,301" Name="LeftListBox"/>
<ListBox Margin="0,29,16,301" Name="RightListBox" HorizontalAlignment="Right" Width="173" />
<Button Name="AddButton" Height="23" Margin="34,135,227,0" VerticalAlignment="Top"
Click="AddButton_Click">Add >></Button>
<Button Name="RemoveButton" Margin="227,135,34,264"
Click="RemoveButton_Click"><< Remove</Button>
</Grid>
For my C# code, I created two methods that loads the left box's elements by using an array of Strings and the right one's.
Now My issue is that I want an element of the left box to be placed into the right box after the last element of the right box's list. So when I click on add, it should execute this method:
private void AddButton_Click(object sender, RoutedEventArgs e)
{
// Find the right item and it's value and index
currentItemText = LeftListBox.SelectedValue.ToString();
currentItemIndex = LeftListBox.SelectedIndex;
ObservableCollection<string> oList;
oList = new System.Collections.ObjectModel.ObservableCollection<string>(toRemoveList);
RightListBox.DataContext = oList;
Binding binding = new Binding();
RightListBox.SetBinding(ListBox.ItemsSourceProperty, binding);
(RightListBox.ItemsSource as ObservableCollection<string>).Add(currentItemText);
if (toAddList != null)
{
toAddList.RemoveAt(currentItemIndex);
}
// Refresh data binding
ApplyDataBinding();
}
But the problem is that when I select an item from the left box, then click on add, it adds the new item into the right box but when I add a second item, it replaces the last one item that I added at the first step.
After that, the second problem is, how would be implemented the RemoveButton_Click ? Is it the same way as the previous method ?
You need not to do this much of code for this. Follow below given steps for more robust and maintainable approach.
Create two Observablecollection corresponding to left and right ListBox
Bind Observablecollection to ListBox
On Add button click, remove the item from observable collection assigned to left listbox and add to the oberservable collection binded to right grid.
You need not to update the bindings explicitly. Observable collection notify the collection changes automatically.
In code -
public ObservableCollection<ApplicationFormats> Formats { get; set; }
Xaml -
<ListBox Name="LeftListBox" ItemsSource="{Binding Formats}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
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 have 2 ListViews and a TextBlock. The first ListView1 includes letters in Alphabetical order. And the second ListView2 includes the words that start with the selected letter (in ListView1). When I choose a letter from ListView1 and then click on a word loaded in ListView2, I want to get the definition of this word in a TextBlock.
This is my Xaml:
<ListView
Width="510"
x:Name="ListView1"
ItemsSource="{Binding}"
Background="White"
Foreground="Black"
TabIndex="1"
Margin="-7,8,0,0"
IsSwipeEnabled="False"
SelectionChanged="ItemListView_SelectionChanged"
Grid.Row="1"
HorizontalAlignment="Left">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Grid.Row="0"
Text="{Binding glossary_letter}"
Margin="10,0,0,0"
TextWrapping="Wrap"
Foreground="Black"
FontSize="24"
FontWeight="SemiBold"
VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Width="361"
x:Name="ListView2"
Background="White"
Foreground="Black"
Margin="425,8,230,0"
Grid.Row="1"
HorizontalAlignment="Center"
ItemsSource="{Binding}"
SelectionChanged="itemListView2_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Grid.Row="1"
TextWrapping="Wrap"
Foreground="Black"
Text="{Binding}"
FontSize="24"
FontWeight="SemiBold"
VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel HorizontalAlignment="Right"
Background="White"
Width="580"
Margin="0,10,0,0" Grid.Row="1" Grid.ColumnSpan="2">
<TextBlock x:Name="defBlock" Foreground="Black" Text="{Binding glossary_definition}"></TextBlock>
</StackPanel>
If I click the first time on a letter (ListView1) then on a word (ListView2) it shows me the definition. However the second time I click on a letter, it gives me an OutOfRange Error where the ListView2.SelectedIndex = -1
This is my C# code:
private void ListView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListView2.ItemsSource = arrayW[ListView1.SelectedIndex];
}
private void ListView2_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
defBlock.Text = arrayDef[ListView1.SelectedIndex][ListView2.SelectedIndex];
}
Any idea what is the error I am doing?
private void ListView2_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(ListView2.SelectedIndex >= 0){
defBlock.Text = arrayDef[ListView1.SelectedIndex][ListView2.SelectedIndex];
}
else
{
defBlock.Text = arrayDef[ListView1.SelectedIndex][0];//set default selected word..
}
}
The problem
You need to manage your list2 selected index changed handler, as every time you update your list one there is a selected index change on list 2 and as there is no selected index it defaults to -1.
There's a number of ways to do this.
1.
private void ListView2_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(ListView2.SelectedIndex == -1)
// do something or
// eg.
return;
// or
throw new IndexOutOfRangeException("Message");
//or
throw new Exception(); // catch all
}
2.
I'm not sure how you want your app to look like.
I'd be using two separate pages for this. And have the xaml for your first list view and then a second page is viewed and bound to the selected index of your first page.
So list1, you select and that then is easier to set as the data source in a new page which shows list2, and then you can update your textbox with the details from a selected item. or further, create a third page if you wanted to show more extensive details of the word and it's definition.
This way you will not have problems with your List2 having no selected index as the data source is changed.
3.
Or,
Take the binding declarations out of the index changed handler and call them methodically when an index is in List1 is selected.So when the selection of List1 is changed, List 2 is updated in other words, you need to update your data source. edit: and with this it's another way of you controlling the use of error handling to avoid an outofrange exception, as the datasource is updated.
So possibly put the following into a separate method.
private void MyTextMethod(){
defBlock.Text = arrayDef[ListView1.SelectedIndex][ListView2.SelectedIndex];
}
private void ListView2_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try{
MyTextMethod)();
}
catch(OutOfRangeException){
// do something.
}
}
out of your selected index changed handler and make a call to a separate method when from within the handler.
4.
Take your binding declaration for list2 from out of your selectedindex change handler for list1.
So you could have a method that will update the binding source of list2 and manage the selected index changed handler. Though this is the least useful suggestion.
Bottom line: You need to have some try and catch, or throw statement managing the outofrange exception, as the second list will have varying lengths and the index on letter As list may be selected at 10, and then the letter X may only have a list of length 1 and there is always the issue of the selectionchange returning a selection of -1.
( You don't actually need to clear list2, it is cleared automatically as the data source is changed (sorry, I didn't make that clear))
I have a list box and i have to display a tick mark on the item selected.I tried this code
List Box
<ListBox Height="691" HorizontalAlignment="Left" Name="listBox1" Margin="-12,71,0,0" VerticalAlignment="Top" Width="480" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,1,0,0" BorderBrush="#FFC1BCBC" Width="490">
<Grid Height="70">
<TextBlock
Name="clients"
Margin="10,12,0,0"
Text="{Binding Name}" FontSize="24" FontWeight="SemiBold" Foreground="Black"></TextBlock>
<Image Height="30" Width="30"
HorizontalAlignment="Left"
Name="imageTick"
Stretch="Fill"
VerticalAlignment="Center"
Source="{Binding strAccountSelectedTickPath}"
Margin="380,0,0,0" Visibility="Collapsed"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
xaml.cs
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
string clientId="";
if (listBox_1.SelectedIndex >= 0)
{
(Application.Current as App).obj_subnodes = newlist[listBox1.SelectedIndex];
if ((Application.Current as App).obj_subnodes.strAccountSelectedTickPath==""||(Application.Current as App).obj_subnodes.strAccountSelectedTickPath==null)
{
if ( (Application.Current as App).obj_subnodes.strAccountSelectedTickPath = "")
{
(Application.Current as App).obj_subnodes.strAccountSelectedTickPath = "/sprinklr;component/Images/IsSelected.png";}
else{ (Application.Current as App).obj_subnodes.strAccountSelectedTickPath = ""; }
initializeListBox();
}
NavigationService.Navigate(new Uri("/Home.xaml, UriKind.Relative));
}
}
private void initializeListBox()
{
listBox1.ItemsSource = "";
listBox1.ItemsSource = newlist;
}
but the problem is suppose ifi have two items in list box say item1 and item2 and at first time i selected item1 and the tick mark displayed on item1 and after that i selected item 2 and the tick marlk displayed on item2 .but the tick mark on item1 doesnot gone.I have to display one tick mark to indicate the selected item,that is i want the tick image to display on the item i clicked.Is there any solution for this.and is there any option to get controll access for the tick image inside the list box.if there is an option i can use imagetick.visibility=visibility.collapsed.but i dont find such an option.is there any solution for this please help me
The best way to achieve this is to change the style / template of the ListBoxItem so that when it is in the 'selected' state, a tick image is displayed.
You need to create a Style that sets the Template for ListBoxItem, adding your tick image within each item. For details of how to do this, see the following blog post. You can apply this style to your ListBox by setting the ItemContainerStyle.
To turn the tick mark on / off based on selection, you will need to add a VisualState to your ListBoxItem Template, which is described in this blog post.
Download the latest Silverlight Toolkit for Windows Phone (or install it via NuGet) and use the MultiselectList instead of a regular ListBox. The MultiselectList supports checkboxes designed to match the functionality of the mail client.
Okay, so I'm fairly new to WPF and data binding, but I've searched and searched and can't seem to find an answer to this.
I have a database (called Inventory), and a dataset (called DevicesDataSet). What I'm trying to do is bind the dataset to a listbox, so that a specific device from the Devices table of the DevicesDataSet can be selected, and have its properties displayed in a TextBox for editing.
The following is the XAML I have so far:
<Window x:Class="Inventory.SignOutDevice"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SignOutDevice" Height="339" Width="392" xmlns:my="clr-namespace:Inventory" Loaded="Window_Loaded">
<Window.Resources>
<my:DevicesDataSet x:Key="devicesDataSet" />
<CollectionViewSource x:Key="devicesViewSource" Source="{Binding Path=Devices, Source={StaticResource devicesDataSet}}" />
</Window.Resources>
<Grid DataContext="{StaticResource devicesViewSource}">
<ListBox Height="237" HorizontalAlignment="Left" Margin="12,12,0,0" Name="listBox1"
VerticalAlignment="Top" Width="254" ItemsSource="{Binding}" SelectedValuePath="Selected">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Make}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Margin="223,267,0,0" Text="{Binding Path=Make, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
Whenever a device is selected and a property is edited (I'm only displaying one property at the moment), the listbox is updated, but the dataset (database?) doesn't seem to be. That is, when I leave the form and then come back to it, the listbox returns to its original state.
So I guess the question is: how do I make these changes persist/write to the database?
Edit: Derp, here's the updated backend C#:
using System.Windows;
using System.Data;
namespace Inventory
{
public partial class SignOutDevice : Window
{
DevicesDataSet devicesDataSet = null;
Inventory.DevicesDataSetTableAdapters.DevicesTableAdapter devicesDataSetDevicesTableAdapter = null;
public SignOutDevice()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
devicesDataSet = ((Inventory.DevicesDataSet)(this.FindResource("devicesDataSet")));
devicesDataSetDevicesTableAdapter = new Inventory.DevicesDataSetTableAdapters.DevicesTableAdapter();
devicesDataSetDevicesTableAdapter.Fill(devicesDataSet.Devices);
System.Windows.Data.CollectionViewSource devicesViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("devicesViewSource")));
devicesViewSource.View.MoveCurrentToFirst();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
devicesDataSet.AcceptChanges();
devicesDataSetDevicesTableAdapter.Update(devicesDataSet.Tables["Devices"].Select(null, null, DataViewRowState.Deleted));
devicesDataSetDevicesTableAdapter.Update(devicesDataSet.Tables["Devices"].Select(null, null, DataViewRowState.ModifiedCurrent));
devicesDataSetDevicesTableAdapter.Update(devicesDataSet.Tables["Devices"].Select(null, null, DataViewRowState.Added));
}
}
}
Have you looked in the Output window to check for binding errors? Because it looks to me like you have one. The TextBox is bound to the Make property, but its DataContext is the devicesViewSource resource. There's nothing associating it with the selected item in the ListBox.
A way to associate the two would be to assign the ListBox a name, and then set the binding on the TextBox to {Binding ElementName=MyListBox, Path=Make, Mode=TwoWay}.
Okay, figured it out. Turns out the auto-generated Update() method in devicesDataSetDevicesTableAdapter didn't actually do anything. Made a custom method with the Query Wizard and now all is well.