Listbox bound to ObservableCollection empty - c#

I have the following xaml:
<Window x:Class="Retail_Utilities.Dialogs.AdjustPriceDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner" Name="Adjust_Price"
Title="Adjust Price" Background="#ee0e1c64" AllowsTransparency="True" WindowStyle="None" Height="330" Width="570" KeyDown="Window_KeyDown" Loaded="Window_Loaded">
<Grid Height="300" Width="550">
<ListBox HorizontalAlignment="Right" Margin="0,110,35,60" Name="lstReasons" Width="120" VerticalAlignment="Stretch"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window, AncestorLevel=1}, Path=reasons}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=POS_Price_Change_Reason}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
Here is the relevant c#:
namespace Retail_Utilities.Dialogs
{
public partial class AdjustPriceDialog : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<Twr_POS_Price_Change_Reason> reasons; ...
and finally, here is the code from another page that opens this window:
AdjustPriceDialog apd = new AdjustPriceDialog();
apd.Owner = (Window)this.Parent;
apd.reasons = new ObservableCollection<Twr_POS_Price_Change_Reason>();
var pcr = from pc in ctx.Twr_POS_Price_Change_Reasons where pc.Deactivated_On == null select pc;
foreach (Twr_POS_Price_Change_Reason pc in pcr)
{
apd.reasons.Add(pc);
}
apd.AdjustingDetail = (Twr_POS_Invoice_Detail)lstDetails.SelectedItem;
if (apd.ShowDialog() == true)
{
}
When the dialog box opens, my lstReasons list is empty. I don't get any errors and when I place a stop in the code, I see that the reasons collection gets populated with the items from the table.

Reasons needs to be a Property (add { get; set;} ). Also, look at Visual Studio Output - it shows Binding errors, there should be some info about failed binding to reasons.

The problem seems to be How you are creating the property.
I know you put your prperty as an observable collection but this doesn't mean it is by it self observalble!
so you need to notify the UI when this property is changed by doing something in the setter like this:
public ObservableCollection<Twr_POS_Price_Change_Reason> reasons
{
get{....}
set
{
Notify('reasons')
}
}
I don't remember the exact code because I didn't use WPF for a while but it is a method in INotifyPropertyChanged, good luck!

It seems your binding path is set to POS_Price_Change_Reason, while the name of your property is reasons. Unless you didn't include POS_Price_Change_Reason in your example code and reasons is the backing field for this property.
Also, keep in mind that you can only bind to public properties, not fields. Additionally, if you change the value of the property, you need to notify the view of this change, by invoking your PropertyChangedEventHandler event for that property:
PropertyChanged(new PropertyChangedEventArgs("YourPropertyName"));

Related

WPF C# Binding Data from another Class

So I'm missing something simple or losing my mind. I am trying to reuse a class for multiple pages in a WPF application and bind the properties to the pages that instance it. I've tried setting the DataContext but I'm missing something. I'm loading the StockAnalysis page and then creating instance of the PriceChart class (this is the class for reuse) and I want the properties set in the PriceChart class to be the data to bind to the Stock.xaml.cs page. Even in setting the DataContext it is still looking for the StockAnalysis object. Why?
Stock.xaml.cs
public partial class StockAnalysis : Page
{
PriceChart PChart = new PriceChart();
public StockAnalysis()
{
InitializeComponent();
//Load The Data
List<Stock> HistoricalPrice = Database.GetPrices(ticker);
//Create The Charts
this.DataContext = PChart;
PChart.ShowPriceChart(HistoricalPrice);
}
}
Stock.xaml (Look at the Last TexBlock for the Binding of "LastPrice")
<Page x:Class="Stock.StockAnalysis"
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"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns:local="clr-namespace:Stock"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1200"
Title="Stock Analysis">
<StackPanel x:Name="LastClosePanel" Grid.Row="0" Grid.RowSpan="2" Grid.Column="5" Height="60" VerticalAlignment="Top" Margin="1,0,0,1" Style="{StaticResource LastCloseBackground}">
<TextBlock x:Name="LastCloseText" Foreground="OrangeRed" FontSize="12" HorizontalAlignment="Center" Margin="0,10,0,8">Last Close</TextBlock>
<TextBlock x:Name="LastCloseBind" Foreground="White" FontSize="16" HorizontalAlignment="Center" Text="{Binding LastPrice}"></TextBlock>
</StackPanel>
</Page>
PriceChart.cs (This is where I assign "LastPrice" in hopes to bind it to the TextBlock in stock.xaml.cs)
public class PriceChart
{
public string LastPrice { get; set; }
public void ShowPriceChart(List<Stock> FullList)
{
LastPrice = FullList[0].LastPrice.ToString("C");
//DO OTHER THINGS
}
}
The problem is that PriceChart doesn't implement any change notification. With the current code, this is how things will go when StockAnalysis gets created:
InitializeComponent() will create the TextBlocks and the binding. At this point, DataContext is null, so the binding will fail and the TextBlock stay empty.
this.DataContext = PChart will trigger a binding update (because DataContext is a DependencyProperty, which means it does support change notification). When the binding updates, it will pull the value of LastPrice, which is currently still empty.
ShowPriceChart will set the value of LastPrice, but because PriceChart doesn't support change notification, the binding doesn't know it needs to update, so the TextBlock stays empty.
To solve this, I would recomend your PriceChart implement the INotifyPropertyChanged interface per this article: How to: Implement Property Change Notification.
(Technically, moving PChart.ShowPriceChart(HistoricalPrice) before this.DataContext = PChart would also "solve" the problem, but only if you never need to update the bindings again after initialization.)

How can I bind a CommandParameter with a child UserControl's child element?

I have the following xaml view:
<UserControl x:Class="MyViews.PersonView"
xmlns:views="clr-namespace:MyViews"
[...]
>
[...]
<dxb:BarManager x:Name="MainBarManager">
<dxb:BarManager.Items>
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
Command="{Binding PrintPersonsCommand}"
CommandParameter="{Binding PersonsCardView, ElementName=CardUserControl}"
/>
</dxb:BarManager.Items>
<Grid>
<Grid.RowDefinitions>
[...]
</Grid.RowDefinitions>
<views:CardView x:Name="CardUserControl" Grid.Row="2"/>
</Grid>
[...]
</UserControl>
The CardView is defined as follows:
<UserControl x:Class="MyViews.CardView"
[...]>
[...]
<dxg:GridControl ItemsSource="{Binding Persons}" SelectedItems="{Binding SelectedPersons}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" SelectionMode="MultipleRow">
[...]
<dxg:GridControl.View>
<dxg:CardView x:Name="PersonsCardView"
[...]
CardTemplate="{StaticResource DisplayCardTemplate}"
PrintCardViewItemTemplate="{StaticResource PrintCardTemplate}"/>
</dxg:GridControl.View>
[...]
</dxg:GridControl>
</UserControl>
The PrintPersonsCommand is defined as follows in my ViewModel:
public class PersonViewModel
{
public PersonViewModel(...)
{
[...]
PrintPersonsCommand = new Prism.Commands.DelegateCommand<DataViewBase>(PrintPersons, CanPrintPersons);
}
public Prism.Commands.DelegateCommand<DataViewBase> PrintPersonsCommand { get; private set; }
private void PrintPersons(DataViewBase view)
{
_printService.ShowGridViewPrintPreview(view);
}
private bool CanPrintPersons(DataViewBase view)
{
return true;
}
}
Now, when I click the Print button, the above PrintPersons method is always fed with null. How do I pass CardUserControl.PersonsCardView in my MyViews.PersonView xaml above, how do I pass that PersonCardView to my command? In other words, how do I fix
CommandParameter="{Binding PersonsCardView, ElementName=CardUserControl}"
to make it work?
Currently, the only solution I've found to this problem is to replace the Command and CommandParameter with
ItemClick="OnPrintBtnClick"
and then in the PersonView's code-behind file to do:
private void OnPrintBtnClick(object sender, ItemClickEventArgs e)
{
var ctxt = DataContext as PersonViewModel;
ctxt.PrintPersonsCommand.Execute(CardUserControl.PersonsCardView);
}
That works but I can't believe there is no other way. I'm not happy with that solution because I don't have the benefits of using the Command any more, like e.g. the automatic evaluation of the Command's CanExecute method. I could also put the CardView's xaml code in the PersonView.xaml but I like my controls to be in separate files because I have the feeling it's more structured and each user control has its own responsibilities which can nicely be split into separate files. Also, that solution binds my view to my view model too tightly.
Can someone help me out please?
Without changing your existing view and viewmodel hierarchy, I was able to pass the GridControl.View to the PersonViewModel using the Tag property
You can assign the CardView to the Tag property at the bottom of your CardView UserControl, and then access this Tag as CommandParameter.
CardView UserControl
<UserControl x:Class="MyViews.CardView"
[...]>
[...]
<dxg:GridControl ItemsSource="{Binding Persons}" SelectedItems="{Binding SelectedPersons}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" SelectionMode="MultipleRow">
[...]
<dxg:GridControl.View>
<dxg:CardView x:Name="PersonsCardView"
[...]
CardTemplate="{StaticResource DisplayCardTemplate}"
PrintCardViewItemTemplate="{StaticResource PrintCardTemplate}"/>
</dxg:GridControl.View>
[...]
</dxg:GridControl>
<UserControl.Tag>
<Binding ElementName="PersonsCardView"/>
</UserControl.Tag>
</UserControl>
Print Button Xaml:
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
Command="{Binding PrintPersonsCommand}"
CommandParameter="{Binding ElementName=CardUserControl, Path=Tag}"
/>
Based on the valuable input of Insane, I came up with the following two cleaner fixes:
Code-behind solution
In the PersonView, use the ItemClick event handler on the Print button:
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
ItemClick="OnPrintBtnClick"/>
Adapt the corresponding code-behind file like this:
public partial class PersonView : UserControl
{
readonly IPrintService _printService;
public PersonView(IPrintService printService)
{
_printService = printService;
InitializeComponent();
}
private void OnPrintBtnClick(object sender, ItemClickEventArgs e)
{
_printService.ShowGridViewPrintPreview(CardUserControl.PersonsCardView);
}
}
Because I want to gray-out the Print button when there is no selection, I still need to add some code to make that happen. I can get it by
1. updating the button code to
<dxb:BarButtonItem x:Name="bbiPrint"
Content="{Binding Print, Source={StaticResource CommonResources}}"
ItemClick="OnPrintBtnClick" IsEnabled="{Binding CanPrintPersons}"/>
refreshing the CanPrintPersons property in the PersonViewModel upon Persons selection change
That's it.
CardViewModel solution
In that solution, we have a PersonView with its underlying PersonViewModel and a CardView with its underlying CardViewModel. I will not describe that solution with all the details as it is overkill in my situation but for the sake of completeness, I'll give the main points. Upon clicking the Print button on the PersonView, the PersonViewModel's PrintCommand is called. That command emits a Print event to the CardViewModel which in turn calls its own PrintCommand. That latter command calls
_printService.ShowGridViewPrintPreview(View);
where the View is a CardViewModel's property that is set upon CardView loading with e.g.
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding ViewLoadedCommand}" CommandParameter="{Binding ElementName=PersonsCardView}" />
</dxmvvm:Interaction.Behaviors>
Because I have two child views I want to print, I'd need to add a view model for each one of those. In addition, those two view models plus the PersonViewModel need access to the list of Persons to be printed. In particular, they need a shared access to the same data, so that they are synchronized. A simple way to do that is explained here and is totally doable. But I think it is not worth the trouble for the simple use case I have as it adds more complexity than necessary.

INotifyPropertyChanged when PropertyChanged

I have:
<Page.Resources>
<data:PublishManager x:Key="pubManager"/>
</Page.Resources>
then in my textBlock i used this:
<TextBlock Grid.Row="2" Canvas.ZIndex="3" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Path=SocialStatus, Mode=TwoWay, Source={StaticResource pubManager}}"></TextBlock>
my class PublishManager look like this:
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _SocialStatus;
public string SocialStatus
{
get
{
return _SocialStatus;
}
set
{
_SocialStatus = value;
RaisePropertyChanged("SocialStatus");
}
}
why when i write in my method code something like this it's don't work for me?
SocialStatus = "StackOverflow";
Why my page with TextBlock don't refresh content?
The problem is that you are using static resource in your binding scenario. Static resources aren't monitored in case of property changes. Do you really need to use your PublishManager as page resource?
It would be better when an instance of PublishManager will be set as DataContext.
So firstly set Page.DataContext:
<Page.DataContext>
<data:PublishManager/>
</Page.DataContext>
And later bind to context property:
<TextBlock Grid.Row="2" Canvas.ZIndex="3" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding SocialStatus}"/>
Do not use the StaticResource here. They are used where resource value is not likely to change. Read below links:
StaticResource
using StaticResource
if the value of SocialStatus is always going to be StackOverflow then declare the static property with that value and your binding should work. else you have to create an object of the class and give it as a datacontext to the view.
Or just create a datacontext when required
<TextBlock Grid.Row="2" Canvas.ZIndex="3" HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Path=SocialStatus, Mode=TwoWay}">
<TextBlock.DataContext>
<data:PublishManager/>
</TextBlock.DataContext>
</TextBlock>
this will work too.
https://msdn.microsoft.com/en-us/library/cc838207%28v=vs.95%29.aspx
binding to a static source works. You just have to make sure data: maps to right namespace. As you did not provide the complete Xaml. you might want to check this.
<UserControl x:Class="PublishManager.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:namespace-to-code">
Although best practice is to use the DataContext to make it more reusable. Like the answer of Patryk provided.

Windows 10 Universal Compiled binding (x:Bind) conflict with ViewModel

I want to bind an element in a page to dependency property in code behind with compiled binding and same time bind another element to ViewModel with usual binding. But it gives a runtime error.
Here is my xaml code.
<Page
x:Class="XbindingProblem.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:XbindingProblem"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
DataContext="{Binding Main, Source={StaticResource Locator}}"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Key="UserDataTemplate" x:DataType="local:User">
<StackPanel>
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Age}" />
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<TextBlock Text="{Binding Title}"/>
<ContentPresenter ContentTemplate="{StaticResource UserDataTemplate}" Content="{x:Bind CurrentUser, Mode=OneWay}"/>
</StackPanel>
</Grid>
Here CurrentUser is dependency property which is initially null and then change in run time. This gives following runtime error.
Incorrect type passed into template. Based on the x:DataType global::XbindingProblem.User was expected.
The problem is it passes the ViewModel into UserDataTemplate instead of CurrentUser dependency property when CurrentUser is null.
Can anyone have a good explanation on this problem?
If you remove DataContext="{Binding Main, Source={StaticResource Locator}}", it will work. Why? because {x:Bind CurrentUser} is looking for a property called CurrentUser sitting inside your MainPage.xaml.cs. Since the CurrentUser is indeed a dependency property of your page, it will just work.
However, by specifying the DataContext of your page, the x:Bind is now excepting a CurrentUser property inside your MainViewModel instance, and of course it's not going to find it, so a compile-time error will be thrown.
One possible fix is to set the this.CurrentUser really early, even before calling InitializeComponent.
this.CurrentUser = new User();
InitializeComponent();
But this is IMHO not the the right way of doing things, as it's basically a racing game - it tries to populate the ContentPresenter before the DataContext gets updated, and in the end you will end up having the TextBlock (of which Text binds to Title) and the ContentPresenter attached to different contexts!
So ask yourself why you need to create a dependency property for CurrentUser inside a Page object, instead of having a normal property (with INotifyPropertyChanged implementation) sitting inside your MainViewModel? I'd prefer the latter, 'cause it's more semantically correct.
The question is interesting, what I have done is just remove the datacontext and this is the code behind is similar to yours:
public sealed partial class BlankPage1 : Page
{
public User CurrentUser
{
get { return (User)GetValue(CurrentUserProperty); }
set { SetValue(CurrentUserProperty, value); }
}
// Using a DependencyProperty as the backing store for CurrentUser. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CurrentUserProperty =
DependencyProperty.Register("CurrentUser", typeof(User), typeof(BlankPage1), new PropertyMetadata(null));
public BlankPage1()
{
this.InitializeComponent();
CurrentUser = new User() { Name = "Hello", Age = "20" };
}
}
public class User
{
public String Name { get; set; }
public String Age { get; set; }
}
might be you have the User class in another namespace or have another class in the typeof(...) of the dependency property. Because I tested that and works. The DataContext of the page can be whatever you want it won't affect.
Then I added the datacontext just to test:
<Page.DataContext>
<local:Main/>
</Page.DataContext>
and the code just for testing:
public class Main
{
public String Title { get; } = "title";
public User MainUser { get; set; }
}
And it does not throws any exception, appears the Main data and the CurrentUser data.
UPDATE. The error happens when the User is null so it is like the x:Bind is null it propagates to the Binding,To solve that (it was tough):
<Page x:Name="Root"
x:Class="Deletetb.BlankPage1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Deletetb"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" >
<Page.DataContext>
<local:Main/>
</Page.DataContext>
<Page.Resources>
<DataTemplate x:Key="UserDataTemplate" x:DataType="local:User">
<StackPanel>
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Age}" />
</StackPanel>
</DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel DataContext="{x:Null}">
<TextBlock Text="{Binding DataContext.Title, ElementName=Root}" />
<ContentPresenter ContentTemplate="{StaticResource UserDataTemplate}" Content="{x:Bind CurrentUser, Mode=OneWay}"/>
</StackPanel>
</Grid>
</Page>
Where is binding defined (TextBlock) I set the datacontext to null in the parent container (StackPanel) and bind by element name, and it does not crash, also I added a wait by code to test and set the Current User and it works. That was a challenge. hope it also works for you.
Although it breaks the idea of MVVM a bit, you can add a property to your page like this:
public MainViewModel viewModel => DataContext as MainViewModel;
And then in the XAML code reference the page property
<ContentPresenter Content="{x:Bind viewModel.CurrentUser, Mode=OneWay}" />

Resharper says OnPropertyChange set member can be private while not true

I use C#, MVVM, WPF and Resharper.
When using the following code:
public bool CombiBanksSelected
{
get { return _selectedBanksType == ESelectedBanksType.CombiBanks; }
set
{
I get a warning of Resharper: Make set accessor private.
When making the set method private, I get an InvalidOperationException: A TwoWay or OneWayToSource binding cannot work on the read-only property ''CombiBanksSelected'' of type ''PcgTools.ViewModels.PcgViewModel.'
Of course I can suppress it by adding:
public bool CombiBanksSelected
{
get { return _selectedBanksType == ESelectedBanksType.CombiBanks; }
// ReSharper disable MemberCanBePrivate.Global
set
// ReSharper restore MemberCanBePrivate.Global
{
But this is not looking nice and not feeling good. Is there a better alternative or solution for this problem?
According to the answer I should change the XAML code. Mine is:
<UserControl x:Class="PcgTools.PcgWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:PcgTools.ViewModels" Height="Auto" Width="Auto"
Loaded="Window_Loaded">
<Grid>
...
<RadioButton Content="_Programs" Height="16" HorizontalAlignment="Left" Margin="12,12,0,0" Name="radioButtonPrograms" VerticalAlignment="Top"
IsChecked="{Binding Path=ProgramBanksSelected}" IsEnabled="{Binding Path=ProgramsEnabled}"/>
<RadioButton Content="_Combis" Height="16" HorizontalAlignment="Left" Margin="85,12,0,0" Name="radioButtonCombis" VerticalAlignment="Top"
IsChecked="{Binding Path=CombiBanksSelected}" IsEnabled="{Binding Path=CombisEnabled}"/>
I have the Resharper problem for both (and more) properties binded to IsChecked (ProgramBanksSelected and CombiBanksSelected in the code above).
In the answer is shown that I should use a DataTemplate, but I still can't figure out how exactly (with not using MVVM light's Locator).
How should I use the data context/template?
Resharper doesn't have enough information to deduce the setter is being used.
For example:
This code:
public partial class Page2
{
public Page2()
{
InitializeComponent();
DataContext = new List<ViewModel>
{
new ViewModel()
};
}
}
public class ViewModel : ViewModelBase
{
private bool _combiBanksSelected;
public bool CombiBanksSelected
{
get { return _combiBanksSelected; }
set
{
Set(()=>CombiBanksSelected, ref _combiBanksSelected, value);
}
}
}
with this Xaml:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="Template" >
<CheckBox IsChecked="{Binding CombiBanksSelected}"/>
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding}" ItemTemplate="{StaticResource Template}" />
</Grid>
will show the setter as not being used (when SWA is turned on).
However if you change the Xaml (adding DataType="{x:Type Samples:ViewModel}") to:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="Template" DataType="{x:Type Samples:ViewModel}">
<CheckBox IsChecked="{Binding CombiBanksSelected}"/>
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding}" ItemTemplate="{StaticResource Template}" />
</Grid>
R# now has enough information and doesn't show the warning.
Of course there are other ways of giving R# and VS Intellisense more hints about the types you're using. Examples are:
Using MVVM Light's view locator:
<UserControl ...
DataContext="{Binding AViewModel, Source={StaticResource Locator}}" />
Using d:DataContext. I recommend looking a this MSDN walkthrough
<UserControl ...
d:DataContext="{d:DesignInstance AViewModel, IsDesignTimeCreatable=true}"
Explicitly setting the DataContext
<UserControl.Resources>
<AViewModel x:Key="theModel/>
</UserControl.Resources>
<Grid DataContext="{StaticResource theModel}"> ...
etc...
Any of these methods allow R# and VS to infer the use of types and provide intellisense.
In addition to Phil's excellent suggestions, you can also use the UsedImplicitlyAttribute. You can use Nuget to do add the dll for you
And then R# will itself offer to decorate the setter with the attribute:
public bool CombiBanksSelected
{
get { return _selectedBanksType == ESelectedBanksType.CombiBanks; }
[UsedImplicitly] set
{
I find it less noisy than a comment, and well suited to a ViewModel where it's understood that data bindings are typically unknown to R#. (sometimes I actually prefer a comment to remind me why I wanted R# to shut up, but not in this case).
Cheers,
Berryl
resharper is a great tool... but it can be wrong occasionally.
You should not annotate your source code with comments to please resharper. Or any other tool for that matter. The tool is wrong, so dont fix the code, fix the tool.
So tell resharper to ignore it. Right click on the icon in the leftmargin and tell it to ignore this kind of problem going forward, or put it in the hint category. I like that option because you can still acess the solution, if it applies, but r# does not show it in the graphical summary on the right.

Categories