RadCombobox does not show correct property value - vb.net

I'm unable to "clear" the current selection from a RadCombobox when needed. This RadCombobox is rebound with new data depending on the value of another radcombobox. After the rebinding, the prior selection should be cleared out. But it still displays. If the prior selection was "OAK", then the combobox still shows OAK as a selection when it should be blank. I find radcomboboxes very tricky to set up so I'm sure it's something dumb on my part.
The Text property of the combobox is bound to woodSpecies which is set up below:
<telerik:RadComboBox x:Name="cboWoodSpecies"
FontSize="16" Background="#F6F8FA" BorderBrush="#D7D8DD"
ItemsSource="{Binding}"
SelectedValue="theWoodSpecies"
Text="{Binding woodSpecies}"
telerik:TextSearch.TextPath="theWoodSpecies"
IsEditable="True"
Style="{DynamicResource RadComboBoxStyle3}" >
<telerik:RadComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding theWoodSpecies}"/>
<TextBlock Grid.Column="1" Text="{Binding WoodSpeciesUpchargeDisplay}"/>
<TextBlock Grid.Column="2" Text="{Binding WoodSpeciesUpcharge}" Visibility="Hidden"/>
</Grid>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
Private _woodSpecies As String
Public Property woodSpecies As String
Get
Return _woodSpecies
End Get
Set(value As String)
_woodSpecies = value
NotifyPropertyChanged("woodSpecies")
End Set
End Property
When it's time to clear the prior selection, this code is run:
thisOrder = New Order 'sets woodSpecies to empty string. Verified by debug.
cboWoodSpecies.SelectedIndex = -1 ' A debug break here shows that thisOrder.woodSpecies is empty string
The only way I can blank out the radcombobox is by using this code below. But I thought that was the whole point of INotifyPropertyChanged.
cboWoodSpecies.Text = String.Empty
How to fix this? Thanks.

I forgot to add Mode=TwoWay to Text="{Binding woodSpecies}"

Related

uwp twoway binding not updating UI

I have the following XAML code, where I have a TextBox for user input (phone number) and GridView for user contacts.
<GridView x:Name="ContactsCollection" Grid.Row="1" Style="{StaticResource DefaultGridView}" IsItemClickEnabled="True" ItemsSource="{Binding UserContacts}" ItemTemplate="{StaticResource HorizontalGridViewDataTemplate}" ItemContainerStyle="{StaticResource DefaultGridViewItemContainer}">
<i:Interaction.Behaviors>
<c:EventTriggerBehavior EventName="SelectionChanged">
<c:InvokeCommandAction Command="{Binding SelectContactCommand}" CommandParameter="{Binding SelectedItem, ElementName=ContactsCollection}"/>
</c:EventTriggerBehavior>
</i:Interaction.Behaviors>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
And my TextBox that is binded to the Recipient in the ViewModel.
<TextBox x:Uid="Recipient" Text="{Binding Recipient, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" PreventKeyboardDisplayOnProgrammaticFocus="True" toolkitControls:TextBoxMask.Mask="7(999)999-99-99" toolkitControls:TextBoxMask.PlaceHolder="X" InputScope="NumericPin" HeaderTemplate="{StaticResource UiControlHeaderDataTemplate}" Style="{StaticResource DefaultTextBoxStyle}"/>
Here goes code from the ViewModel.
public string Recipient
{
get { return _recipient; }
set
{
if (value != _recipient)
{
_recipient = value;
RaisePropertyChanged(nameof(Recipient));
ContinueTransferCommand.RaiseCanExecuteChanged();
}
}
}
Now, when I click any contact from the GridView the following functions is called, that assign contact's phone number to the Recipient property.
private void SelectContactCommandAction(object contact)
{
Contact c = contact as Contact;
if (c.Phones?.Count > 0)
Recipient = FormatDataHelper.FormatPhoneNumber(c.Phones.FirstOrDefault().Number);
}
When I click any contact for the FIRST time, the Recipient property is updated, and the UI is updated too. But, if I select other contact, in the debug mode I can see, that Recipient property is updated and saved new value, but the UI (TextBox) is not updated at all. The only way it works, I have to delete any character from the TextBox and select a contact again, in that case UI value will be updated again.
Can somebody please explain this?

UWP : Setting the Width and Height of controls as percentage values

I am trying to use a StackPanel control to display some overview options. I need to have this control using 20% of the window width when the MinWindowWidth is greater than 768px. When this is run on mobile I need the control to fill the width of the screen.
I tried as suggested in this question to try and set a value in percentage. However, I get the error - "* string cannot be converted to length".
Here is my XAML -
<StackPanel x:Name="OverviewStack">
<RelativePanel>
<StackPanel Margin="10" x:Name="User" Orientation="Horizontal">
<Ellipse Margin="5" Width="50" Height="50">
<Ellipse.Fill>
<ImageBrush>
<ImageBrush.ImageSource>
<BitmapImage UriSource="Assets/insp.jpg" />
</ImageBrush.ImageSource>
</ImageBrush>
</Ellipse.Fill>
</Ellipse>
<TextBlock Margin="5" VerticalAlignment="Center" Text="Ajay Kelkar" />
</StackPanel>
<StackPanel Margin="10" x:Name="Options" Orientation="Vertical">
<TextBlock Margin="5" Text="Sample text" />
</StackPanel>
</RelativePanel>
</StackPanel>
Is a percentage value not possible in UWP? Or am I doing something wrong?
You need to determine which platform you're currently on, and set the value accordingly.
This sounds like a converter.
Since you only have 1 project for UWP you'll need to check in the converter which platform you're on. such info can be acquired as such:
if (AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
{
//Act accordingly
}
So I think you'd like to do something like this:
public object Convert(object value, Type targetType, object parameter, string language)
{
// bind the width as the value the converter is set upon
var width = double.Parse(value.ToString());
if (AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
{
return width;
}
// You weren't clear exactly regarding the 768px thing so act accordingly here
return width * 0.2d;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}

Why is this XAML failing with "The property "Content" can only be set once."?

I've got this XAML:
<AppBarButton Icon="Protected" Label="Privacy Policy" >
<AppBarButton.Flyout>
<StackPanel>
<Flyout>
<TextBlock Text="Photrax extracts information from images you load into it. The information it extracts includes location information (where the photos were taken, when that is available) and the date and time the photo was taken. This data is stored in a local/internal/embedded (SQLite) database. This data is not stored in the cloud but only on your local device." TextWrapping="Wrap" FontSize="26" FontFamily="Verdana">
</TextBlock>
<TextBlock Text="To reiterate: Your data is not shared with anyone else. It is stored only on the device from which you use Photrax." TextWrapping="Wrap" FontSize="26" FontFamily="Verdana">
</TextBlock>
</Flyout>
</StackPanel>
</AppBarButton.Flyout>
</AppBarButton>
...which fails with, "The property "Content" can only be set once."
Why is there a problem with this, when the following XAML, which is basically the same, compiles fine:
<AppBarButton Icon="MapPin" Label="Colors In Use" Tapped="appbarbtnPhotosetColorMapping_Tapped">
<AppBarButton.Flyout>
<Flyout>
<StackPanel Background="Azure">
<TextBlock Text="Photoset:Pushpin Color Legend" TextWrapping="Wrap" FontSize="26" FontFamily="Verdana"></TextBlock>
<TextBlock x:Name="textblock0" Text="Unused" Foreground="Red" FontFamily="Segoe UI" FontSize="13" Margin="4" />
. . .
?
I get other err msgs with that xaml, too (about the following types being expected: flyoutbase and uielement), but I think it's the Content business that is giving me the business.
I pasted the problem code into kaxaml, but it doesn't even know what an AppBarButton is, and complained about that being an invalid element.
UPDATE
I can't test it yet, but I'm thinking that what Abdallah means is that I need to change this:
<StackPanel>
<Flyout>
. . .
</Flyout>
</StackPanel>
...to this:
<Flyout>
<StackPanel>
. . .
</StackPanel>
</Flyout>
You have two problems here :
1) The property "Content" can only be set once. :
You can't set the content for <Flyout> </Flyout> more than once and you set the content twice (Two TextBlocks) in first XAML code and in the working XAML once(One StackPanel), According to MSDN :
<Flyout>
singleUIElement
</Flyout>
singleUIElement :
A single object element that declares the content. This must be an
object that has UIElement in its hierarchy (plain strings don't work).
This can be a container, such as a Panel derived class, so that
multiple content items within the Flyout can be arranged in layout.
2) The following type was expected: "FlyoutBase".
You can't set Flyout property to any class that not derived from FlyoutBase class (i.e only Flyout and MenuFlyout ). you set the Flyout property in first XAML code to StackPanel and in the working XAML to Flyout .

How to get the index of an item in an itemscontrol

I want to show the current index of an item in an itemscontrol:
<TextBlock Foreground="#ffffffff" Margin="8,8,2,2" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Items.CurrentIndex}" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right"/>
This is my best guess. I've come across many possible solutions, but working with alternationcount (not supported in silverlight as it seems) or other didn't give me a result.
The itemscontrol looks like this:
<ItemsControl Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" Grid.Row="6" ItemsSource="{Binding Alternatives, Mode=TwoWay}" ></ItemsControl>
The list bound to the itemscontrol is a simple object with some properties.
I really like to do this in XAML, as we reuse that object on alot of pages.
Any good suggestions would be great.
PS: I don't want the index after interaction from the user, it should be retrieved automatically.
if you want the index of an item in an itemscontrol - it just make sense for me if there is some sort of selection. but the itemsscontrol has no selector and so no selection and so no selectionchanged event. so if you want some selection take listbox
one more thing
<ItemsControl ItemsSource="{Binding Alternatives, Mode=TwoWay}" ></ItemsControl>
mode=twoway makes no sense, cause your itemsscontrol will never set the underlining source.
EDIT: i just assume what you want from your comment. you can use a ICollectionView to iterate through your items. but your Itemscontrol can not show this of course. but you can alter the item itself to show the iteration
ICollectionView view = CollectionViewsource.GetDefaultView(Alternatives);
view.CurrentChanged += (s,a) =>
{
var current = this.view.CurrentItem;
//to stuff with your current item here
};
elsewhere where you want to iterate
view.MoveCurrentToNext();
you should handle first and last item and that stuff too.

How to show part of text in datagrid row details?

I have table in my database which has fields of ID,NAME,CONTEXT. I am showing search result in datagrid. Now I tried to do this
<WpfToolkit:DataGrid.RowDetailsTemplate>
<DataTemplate>
**<StackPanel Orientation="Horizontal" Margin="5">
<StackPanel Orientation="Vertical" Margin="5">
<TextBlock Foreground="CadetBlue" FontSize="13"
Width="Auto" TextWrapping="Wrap"
Text="{Binding Path=Context}"/>
</StackPanel>**
</StackPanel>
</DataTemplate>
</WpfToolkit:DataGrid.RowDetailsTemplate>
It is giving whole text which is not what I want. If you give me some directions how to do this, may be some code. It will be appreciated. I want to show only that part of text which is selected by this line of code.
private void Find_Click(object sender, RoutedEventArgs e)
{
DataSet ds = new DataSet();
cmdSel = new SqlCommand();
cmdSel.Connection = MainWindow.conn;
cmdSel.CommandText = "select id,Name,Context from document where Contains([Context],'FormsOf (INFLECTIONAL, \"" + TextBoxSearch.Text + "\")')";
da = new SqlDataAdapter(cmdSel);
da.Fill(ds, "MainSearchBinding");
resWin.DataGrid1.DataContext = ds;
}
For example you are searching for "audio" and it is showing 10 words before + "audio" + 10 word after audio. Thank in advance.
I add one more column "Intro" to my table.
<WpfToolkit:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5">
<StackPanel Orientation="Vertical" Margin="5" >
<TextBlock Foreground="CadetBlue" FontSize="13"
Width="Auto" TextWrapping="Wrap"
Text="{Binding Path=Intro}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</WpfToolkit:DataGrid.RowDetailsTemplate>
And wrote this code for mouse click.
private void OnMouseClick(object sender, MouseButtonEventArgs e)
{
IList rows = DataGrid1.SelectedItems;
DataRowView row = (DataRowView)DataGrid1.SelectedItems[0];
int a = (int)row["ID"];
string t = (string)row["Context"]; //getting all text from Context
string srch1 = UCSearch.srch; // search box text
if (t.IndexOf(srch1) != -1)
{
string retString = t.Substring(t.IndexOf(srch1), 100); //cutting from occured text and more 100 symbols
row["Intro"] = retString; // setting to Intro Column
}
}
I hope some one may need it. Thank you.