Changing MVVM ListView SelectedItem in code throws 'Value does not fall within the expected range' - xaml

I'm developing a Windows 8.1 Universal App using the MVVM Light Toolkit.
I have a ListView
<ListView
x:Name="MyListView"
ItemsSource="{Binding ModelCollection, Mode=TwoWay}"
SelectedItem="{Binding CurrentModelItem, Mode=TwoWay}"
and my ViewModel is as it follows:
public class PageViewModel : ViewModelBase
{
private ObservableCollection<MyViewModel> _modelCollection =
new ObservableCollection<MyViewModel>();
public ObservableCollection<MyViewModel> ModelCollection
{
get { return _modelCollection ; }
set { Set(() => ModelCollection , ref _modelCollection , value); }
}
private MyViewModel _currentModelItem;
public InspectionDiscrepancyViewModel CurrentModelItem
{
get { return _currentModelItem; }
set { Set(() => CurrentModelItem, ref _currentModelItem, value); }
}
If I let the CurrentModelItem item at load time it works 'fine' but if I try to set the CurrentModelItem in the LoadData Method -that populates the ObservableCollection- to the first ModelCollection Item
CurrentModel = ModelCollection.FirstOrDefault();
I get the following error on the Set() Method of the MVVM Light Toolkit:
An exception of type 'System.ArgumentException' occurred in mscorlib.dll but was not handled in user code
Additional information: Value does not fall within the expected range.
I've seen that doing this should be very straightforward, what am I doing wrong here?

Related

How to prepopulate Autocomplete SelectedItem

From my previous post, it helped be to determine how to bind to selecteditems, How to bind to autocomplete selecteditem with ObservableCollection But now I'm trying to enhance that logic.
I'm trying to have items preselected when my View is initialized. I've tried multiple options, but I can't seem to get items preselected. May I get some assistance. My current code below
Keyword Class
public class Keyword : ObservableObject
{
private string _value;
public string Value
{
get { return _value; }
set { SetProperty(ref _value, value); }
}
}
ViewModel
private ObservableCollection<object> _selectedKeywords = new ObservableCollection<object>();
private ObservableCollection<Keyword> _keywords = new ObservableCollection<Keyword>();
public TestViewModel()
{
Keywords = new ObservableCollection<Keyword>()
{
new Keyword { Value = "Apples" },
new Keyword { Value = "Bananas" },
new Keyword { Value = "Celery" }
};
SelectedKeywords = new ObservableCollection<object>(Keywords.Where(x => x.Value == "Apples"));
}
public ObservableCollection<object> SelectedKeywords
{
get { return _selectedKeywords; }
set { SetProperty(ref _selectedKeywords, value); }
}
public ObservableCollection<Keyword> Keywords
{
get { return _keywords; }
set { SetProperty(ref _keywords, value); }
}
View
<autocomplete:SfAutoComplete MultiSelectMode="Token"
HorizontalOptions="FillAndExpand"
VerticalOptions="EndAndExpand"
TokensWrapMode="Wrap"
Text="{Binding Keyword, Mode=TwoWay }"
IsSelectedItemsVisibleInDropDown="false"
Watermark="Add..."
HeightRequest="120"
SelectedItem="{Binding SelectedKeywords}"
DataSource="{Binding Keywords}">
</autocomplete:SfAutoComplete>
We have prepared sample from your code snippet and you have missed to add DisplayMemberPath property in the code snippet. Please find the sample from below location.
http://www.syncfusion.com/downloads/support/directtrac/general/ze/AutoCompleteSample-270923957.zip
Note: I work for Syncfusion.
Regards,
Dhanasekar
To make it preselected in your View Model set a value to the binding that you have binded on your View basically assign a value to SelectedKeywords
Something like:
SelectedKeywords = Keywords.FirstOrDefault();
You might need two-way binding not sure cause never used this control:
SelectedItem="{Binding SelectedKeywords, Mode=TwoWay}"

How to dynamically bind data in WPF notify Icon window

Hello I want to create notify icon to my task-bar and when I click that icon one popup window open and that popup showing me which tasks are I have to complete today and also want to show today's appointment list.
Doubts
Suppose I get 10 task from database for today's date then All task should be display with scroll bar.
How to bind data with WPF control([textBlock])?
How to create [textBlock] control dynamically means Suppose I get task description from description column then it display otherwise description [textBlock] is not create.
I have refereed following link to achieve this.
http://www.codeproject.com/Articles/36468/WPF-NotifyIcon
but I really don't know how to bind data with WPF application.
Edit the FancyPopup.xaml
Add:
<ListView ItemsSource="{Binding TasksCollection, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TaskName}"/>
</DataTemplate>
<ListView.ItemTemplate/>
</ListView>
In the code behind you can set your view model like this:
public FancyPopup()
{
InitializeComponent();
this.DataContext = new PopupViewModel();
}
And then in your ViewModel:
public ObservableCollection<TaskDataModel> tasksCollection;
public ObservableCollection<TaskDataModel> TasksCollection
{
get
{
if (tasksCollection == null)
{
tasksCollection = new ObservableCollection<TaskDataModel>();
}
return tasksCollection;
}
set
{
tasksCollection = value;
this.OnPropertyChanged("tasksCollection");
}
}
Where TaskDataModel is class describing your data model.
public class TaskDataModel : INotifyPropertyChanged
{
public TaskDataModel()
{
}
private string taskName;
public string TaskName
{
get { return taskName; }
set
{
if (taskName != value)
{
taskName = value;
OnPropertyChanged("TaskName");
}
}
}
}

"Hello World" with ReactiveUI, Xamarin Forms and XAML locking up

I'm trying to do a hello world with Reactive UI and Xamarin Forms.
I have created a ViewModel (based on ReactiveObject), a custom page (based on ReactiveContentPage) and some XAML markup.
The page has an entry and a Label, bound together. When I run it (on iOS and Android), it appears to work for the first few characters typed, then locks up. The console gives a 'too much is happening on the main thread' warning.
What am I missing?
The project is here.
The Model
namespace XamarinFormsReactiveUIExample
{
public class MyPageModel : ReactiveObject
{
private string _userName = "";
public string UserName {
get { return _userName; }
set { this.RaiseAndSetIfChanged (ref _userName, value); }
}
}
}
The Page
namespace XamarinFormsReactiveUIExample
{
public partial class MyPage : ReactiveContentPage<MyPageModel>
{
public MyPage ()
{
InitializeComponent ();
}
}
}
The XAML
<?xml version="1.0" encoding="UTF-8"?>
<reactive:ReactiveContentPage
x:TypeArguments="local:MyPageModel"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinFormsReactiveUIExample.MyPage"
xmlns:local="clr-namespace:XamarinFormsReactiveUIExample;assembly=XamarinFormsReactiveUIExample"
xmlns:reactive="clr-namespace:ReactiveUI.XamForms;assembly=ReactiveUI.XamForms">
<reactive:ReactiveContentPage.BindingContext>
<local:MyPageModel />
</reactive:ReactiveContentPage.BindingContext>
<reactive:ReactiveContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="0, 150, 0, 0" />
</reactive:ReactiveContentPage.Padding>
<reactive:ReactiveContentPage.Content>
<StackLayout>
<Entry Text = "{Binding UserName}"></Entry>
<Label Text = "{Binding UserName}"></Label>
</StackLayout>
</reactive:ReactiveContentPage.Content>
</reactive:ReactiveContentPage>
I don't see how this could be anything but a Xamarin bug, ReactiveUI isn't doing anything here. Anyways, you can always try to write these bindings the RxUI way:
<Entry x:Name="userNameEntry" />
<Label x:Name="userNameLabel" />
Then, in the constructor:
public MyPage ()
{
InitializeComponent();
this.ViewModel = new MyPageModel();
this.Bind(ViewModel, vm => vm.UserName, v => v.userNameEntry.Text);
this.OneWayBind(ViewModel, vm => vm.UserName, v => v.userNameLabel.Text);
}
The only thing I saw missing was the ViewModel was never instantiated, and the Binding Context was never set. I can't see what your old code did before you changed it to the new style. Personally, I try to avoid using code behind as much as possible as well. So you should be able to modify your constructor to something like,
public MyPage ()
{
InitializeComponent();
this.ViewModel = new MyPageModel();
this.BindingContext = ViewModel;
}
And revert to using your XAML binding.

Value of property binded to a TextBlock inside a User Control is not being detected

I've created a UserControl, LiveTile.xaml (streamlined for brevity):
<UserControl
x:Class="Weathercast.Core.LiveTile"
xmlns:local="clr-namespace:Weathercast.Core">
<StackPanel
x:Name="LayoutRoot">
<StackPanel
x:Name="TileRegularFront"
Width="336"
Height="336"
Background="Red">
<TextBlock Text="{Binding TempCurrentHour}"/>
</StackPanel>
</UserControl>
Its code behind, LiveTile.xaml.cs:
public partial class LiveTile : UserControl
{
public LiveTile()
{
InitializeComponent();
LiveTileViewModel vm = new LiveTileViewModel();
this.DataContext = vm;
}
}
Its view model, LiveTileViewModel.cs:
public class LiveTileViewModel : ObservableObject
{
/** PROPERTIES **/
private string _tempCurrentHour;
public string TempCurrentHour
{
get { return _tempCurrentHour; }
set
{
_tempCurrentHour = value;
RaisePropertyChanged("TempCurrentHour");
}
}
/** CONSTRUCTOR **/
public LiveTileViewModel()
{
this.TempCurrentHour = "15"; // dummy value set
}
}
ObservableObject.cs:
public abstract class ObservableObject : INotifyPropertyChanged, INotifyPropertyChanging
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
The problem is the value I'm binding ("TempCurrentHour") is not being displayed. Any ideas on what I need to do in order to get the User Control's View Model's binded property value to display? Based on my research, I believe binding a value to a User Control is less straightforward than normal. However I can't get my head around what needs to be done to get the User Control to detect binded property values.
UPDATE: Just to be clear, the LiveTile class is in a Library project for my solution. An instance of it is created when the user toggles on the Live Tile via the Settings PhoneApplicationPage located in the Windows Phone App project in the solution. This is the event handler that instantiates a LiveTile in Settings.xaml.cs:
private void LiveTile_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Weathercast.Core.LiveTile l = new Weathercast.Core.LiveTile();
l.CreateOrUpdateTile(1);
}
The CreateOrUpdateTile method is doing its job correctly and takes the user back to their phone's Start screen with the Live Tile now there. This is its code in any case (I'm using Telerik's LiveTileHelper):
RadFlipTileData tileData = new RadFlipTileData()
{
VisualElement = this.TileRegularFront,
BackVisualElement = this.TileRegularBack,
SmallVisualElement = this.TileSmall
};
// Tile's uri has a unique paramater which is the location Id of the currently viewed location.
Uri tileUri = new Uri("/MainPage.xaml?locationId=" + locationId, UriKind.RelativeOrAbsolute);
// If the tile for this location previously existed, delete it before adding it anew.
ShellTile tile = LiveTileHelper.GetTile(tileUri);
if (tile != null)
{
tile.Delete();
}
// Create brand new tile for location if didn't have tile previously or fresh tile if it did.
LiveTileHelper.CreateOrUpdateTile(tileData, tileUri, true);
this.tile = tileData;
// Add the Background Agent for this tile with the agent's name
// unique for the location.
AddAgent("PeriodicTaskForLocation" + locationId);
I should note another problem I'm having, that may or may not be related to the original issue, is that the background property I'm setting in LiveTile.xaml for the StackPanel or LayoutRoot element even is being neglected and the Live Tile that's being added to the Start screen is transparent (black).

Binding telerik control to a visibility property throws a runtime error

I'm having an issue when I try to bind a visibility property to a telerik control.
When I bind the same property to a regular control, it works fine.
I've tried both, Visibility.Collapsed and Telerik.Windows.Controls.Charting.SeriesVisibility.Collapsed, but I still get the following error
Set property
'Telerik.Windows.Controls.Charting.SeriesDefinition.Visibility' threw
an exception.
This error is thrown on the Initialize();
Here's my code
View (code behind):
public ChartView(ViewModel viewModel)
{
InitializeComponent();
}
ViewModel:
private Telerik.Windows.Controls.Charting.SeriesVisibility _startDateVisible;
public Telerik.Windows.Controls.Charting.SeriesVisibility StartDateVisible
{
get {return _startDateVisible;}
set
{
_startDateVisible = value;
OnPropertyChanged("StartDateVisible");
}
}
public ViewModel(IEventAggregator eventAggregator)
: base(eventAggregator)
{
StartDateVisible = Telerik.Windows.Controls.Charting.SeriesVisibility.Collapsed;
//StartDateVisible = Visibility.Collapsed;
}
View (XAML):
<telerikCharting:SeriesMapping x:Name="..." LegendLabel="..." CollectionIndex="1" ChartAreaName="...">
<telerikCharting:SeriesMapping.SeriesDefinition>
<telerikCharting:ScatterSeriesDefinition ShowItemLabels="True" ShowItemToolTips="True" PointShape="Circle" Visibility="{Binding StartDateVisible}" />
</telerikCharting:SeriesMapping.SeriesDefinition>
<telerikCharting:SeriesMapping.ItemMappings>
<telerikCharting:ItemMapping DataPointMember="XValue" FieldName="..."/>
<telerikCharting:ItemMapping DataPointMember="YValue" FieldName="..."/>
</telerikCharting:SeriesMapping.ItemMappings>
</telerikCharting:SeriesMapping>
Found out it's impossible due to dependency issues.
http://www.telerik.com/community/forums/silverlight/chart/seriesdefinition-visibility-binding-issue.aspx