I am trying to set my datacontext in the XAML file via
<Window x:Class="LocationScout.SettingsDeleteWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="clr-namespace:LocationScout.ViewModel"
mc:Ignorable="d"
Title="Delete" Height="315" Width="350"
WindowStartupLocation="CenterScreen">
<Window.DataContext>
<ViewModel:SettingsDeleteDisplayItem/>
</Window.DataContext>
The XAML editor, however, shows the error "The name "SettingsDeleteDisplayItem" does not exist in the namespace "clr-namespace:LocationScout.ViewModel".
The view model class looks fine for me:
namespace LocationScout.ViewModel
{
public class SettingsDeleteDisplayItem : BaseObservableObject
{
private long _countryAreaCountToDelete;
public long CountryAreaCountToDelete
{
get => _countryAreaCountToDelete;
set
{
_countryAreaCountToDelete = value;
OnPropertyChanged();
}
}
}
}
Building the solution works fine without error. Any idea? Many thanks.
As advised by #RobertHarvey in a comment, I changed to lowercase and restarted Visual Studio:
try changing ViewModel to lower case, as in xmlns:viewModel.
The reason this might have been an issue is because ViewModel (in
upper case) appears in your namespace declarations.
Now it works.
Just rebuilding the solution did not help (I tried that earlier).
Related
I'm trying to refactor the property MyText to a new name HerText in the following solution:
MainWindow.xaml.cs
using System.Windows;
namespace resharper_refactoring_xaml
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyText = "Blabla";
DataContext = this;
}
public string MyText { get; set; }
}
}
MainWindow.Xaml
<Window x:Class="resharper_refactoring_xaml.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:resharper_refactoring_xaml"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBlock Text="{Binding Path=MyText}"></TextBlock>
</Grid>
</Window>
I right click on the property and select Refactor this > Rename. Then I type in a new name for the property, hit Next.
Unfortunately, only the references of MyText in the code-behind are renamed. References to MyText in the XAML file rename intact.
According to this question Resharper should be able to propagate refactorings to XAML files.
Why is the rename not propagating to the XAML file? Is there some sort of Resharper setting I might have overlooked?
The reason behind this seems to be that ReSharper cannot determine that the property name specified in the XAML markup refers to the property defined in the MainWindow class, if the DataContext property is set in code-behind.
Bindings refer to the DataContext of controls as source by default. If it is not detected, the link between the loose markup and the defining type is lost. I cannot tell if this is a bug in ReSharper or a general limitation.
However, there are two simple solutions to this issue that work for me:
Set a design time data context to the type that defines the property here MainWindow.
<Window ...
d:DataContext="{d:DesignInstance Type={x:Type local:MainWindow}}">
Set the data context via binding in XAML instead of code-behind.
<Window ...
DataContext="{Binding RelativeSource={RelativeSource Self}}">
I'm not getting intellisense suggestions for properties that were source generated by the MVVM community toolkit. Is there a way to fix this? If I can't get the suggestions to work, then using [ObservableProperty] isn't even worth it IMO. Example below.
ViewModel has one source generated property and one handmade property:
public partial class SimplisticViewModel : ObservableObject
{
[ObservableProperty]
private int sourceGeneratedProperty;
private float handmadeProperty;
public float HandmadeProperty
{
get => handmadeProperty;
set => SetProperty(ref handmadeProperty, value);
}
}
XAML:
<Window x:Class="WPFEFTest.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFEFTest"
mc:Ignorable="d"
Title="TestWindow" Height="450" Width="800">
<Window.DataContext>
<local:SimplisticViewModel/>
</Window.DataContext>
<StackPanel>
<TextBox Text=""/>
</StackPanel>
</Window>
When setting up binding for the handmade property, the suggestions work:
When setting up binding for the source generated property, there are no suggestions:
However, if I write the entire property name (avoiding typos and such...) and hover my cursor over it (cursor not visible in screenshot), intellisense will correctly show the type of the property. So the problem probably isn't that intellisense doesn't "see" the property at all.
EDIT: To make it clear I'm not trying to bind to a field, below is code that MVVM community toolkit generates because of the ObservableProperty attribute:
public partial class SimplisticViewModel
{
[global::System.CodeDom.Compiler.GeneratedCode("Microsoft.Toolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "7.1.0.0")]
[global::System.Diagnostics.DebuggerNonUserCode]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public int SourceGeneratedProperty
{
get => sourceGeneratedProperty;
set
{
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(sourceGeneratedProperty, value))
{
OnPropertyChanging(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.SourceGeneratedPropertyPropertyChangingEventArgs);
sourceGeneratedProperty = value;
OnPropertyChanged(global::Microsoft.Toolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedOrChangingArgs.SourceGeneratedPropertyPropertyChangedEventArgs);
}
}
}
}
Maybe you could try setting DataContext for window... Same thing/issue you describe happens when I remove d:DataContext which points to ViewModel class and when DataContext is set, Intellisense picks up properties from ViewModel.
<Window x:Class="WPFEFTest.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFEFTest"
xmlns:viewmodels="clr-namespace:WPFEFTest.ViewModels"
mc:Ignorable="d"
Title="TestWindow" Height="450" Width="800" d:DataContext="{d:DesignInstance Type=viewmodels:SimplisticViewModel>
I am having a problem with the Visual Studio designer for a WPF project and the combination of binding to a type using a generic and specifying a nullable type as the generic type.
I have tried to construct a minimal example of the problem:
XAML:
<Window x:Class="TestWpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestWpfApp"
mc:Ignorable="d" d:DataContext="{d:DesignInstance local:TestViewModel}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBlock Text="{Binding TestText.Value}"/>
<!--<TextBlock Text="{Binding TestTextValue}"/>-->
</Grid>
</Window>
Code behind:
using System.Windows;
namespace TestWpfApp
{
public class TestGeneric<T>
{
public TestGeneric(T value)
{
Value = value;
}
public T Value { get; }
}
public class TestViewModel
{
public TestGeneric<double?> TestText { get; } = new TestGeneric<double?>(123.456);
public double? TestTextValue => TestText.Value;
}
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new TestViewModel();
InitializeComponent();
}
}
}
The designer fails with this code with the following error message:
System.Runtime.Remoting.RemotingException
[16040] Designer process terminated unexpectedly!
The commented out line in the XAML code does not give the error in the designer window.
Both versions actually work when running the project. It is only the designer that fails.
Does anyone have any idea about what the problem could be?
The d:DataContext design time expression is a very practical trick, and IDE related, it has no impact on the runtime, only affect the design time. Applicable in Visual Studio 2010 and later.
The default constructor is required for a type to be instantiated in XAML.
The option IsDesignTimeCreatable=True tells the designer that it can create the specified class via default constructor. This way it is possible to provide sample data for the UI.
d:DataContext="{d:DesignInstance local:TestViewModel , IsDesignTimeCreatable=True }"
Yong Lu
I found myself stuck in this little problem that seems to have no solution at all. I'm trying to set the DataContext to a Window in WPF Project that looks like this:
The XAML file:
<Window x:Class="CSB.Tasks.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CSB.Tasks"
xmlns:vm="clr-namespace:CSB.Tasks.ViewModels.WPF" <!-- This is what i need -->
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<WindowChrome.WindowChrome>
<WindowChrome ResizeBorderThickness="{Binding ResizeBorderThickness}"
GlassFrameThickness="0"
CornerRadius="{Binding CornerRadius}"/>
</WindowChrome.WindowChrome>
<StackPanel Margin="5">
</StackPanel>
I want to set WindowViewModel as the ViewModel of the Window, but VS doesn't seem to find the folders where the class is contained. So, when I try to add the Window.DataContext like:
<Window.DataContext>
<vm:WindowViewModel/>
</Window.DataContext>
VS obviously tells me that the class does not exist.
I've been searching for similar questions on SO and I found plenty of them, but no one actually helped me. I already tried restarting VS, cleaning and rebuilding the project, compiling on a specific target platform (now it's set to Any CPU), moving the ViewModel in the root folder and then moving it back, absolutely no changes.
Does anyone know what could the cause be?
Thank you in advance for the help.
I actually managed to add the DataContext to the MainWindow XAML. The namespace of the ViewModel was set to CSB.Tasks in order to access it globally, but even using the local xmlns I couldn't be able to reference it. I had to change the namespace of the ViewModel according to its actual path in the project folder, so:
namespace CSB.Tasks.ViewModels.WPF
{
public class WindowViewModel : BaseViewModel
{
...
}
}
In order to set the xmlns:vm and to use it in the DataContext declaration. Then I switched the ViewModel namespace back to CSB.Tasks and recompiled the project and for some reason in the XAML editor I could be able to access WindowViewModel from the xmlns:local.
It's not very clear to me if this is a bug or not.
Thank you all for the help!
MainWindow.xaml:
<Window x:Class="View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Nothing" Height="600" Width="800" MinHeight="450" MinWidth="400"/>
Mainwindow.xaml.cs:
using System.Windows;
namespace View
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
It throws an error. The namespaces are correct, i tried rebuilding the solution, cleaning the solution, the xaml build action is set to Page. The same code worked before, then i changed the View namespace to View2 in both files, it started throwing errors, so i changed it back, but the same error appears. Is there anybody who solved this bug somehow (without creating a new solution and copying the files, which would obviously solve the problem)?