|
The easiest way would be to create a named style and apply that. This would be applied to the TextBlock inside your HyperLink.
This space for rent
|
|
|
|
|
So give both the Link and textblock names, then create a named style for them in my Main project?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
But in the style, how do you specified which element in the control the style items are applied to?
How do you apply a stlye to each of the elements in the control from with in the style?
<Style x:Key="HyperlinkViewStyle"
TargetType="{x:Type myControls:HyperlinkView}">
How do do style the TextBlock or the Hyperlink in here?
</Style>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 2-Feb-17 13:57pm.
|
|
|
|
|
I realize that this is not a Telerik forum but I also poured through their forums to no avail. Long story short, I am using NHibernate to hydrate my viewmodels and exposing complex objects with their related objects to my view. The issue is that in my grid I have a combobox column that has a collection of objects from the viewmodel, the selectedvalue of which will update the object of the selected item. When I change the combobox everything is great, everything is talking back and forth, all is well. But when I close the control and reopen it, it does not select any value for the column.
All code is cut for brevity:
View:
<telerik:GridViewComboBoxColumn x:Name="Client"
ItemsSource="{Binding Clients}"
DataMemberBinding="{Binding Client}"
DisplayMemberPath="Name"
SelectedValueMemberPath=""
Header="Client"
Width="125" />
ViewModel:
public ObservableCollection<Client> Clients { get; private set;}
Entity:
public class Claim : Entity<int>
{
public virtual Client Client { get; set; }
}
NHibernate Mapping
public ClaimMap()
{
Table("Claim");
LazyLoad();
Id(x => x.Id).GeneratedBy.Identity().Column("id");
References(x => x.Client).Column("clientId").Not.Nullable();
}
}
}
I am sure I could just expose the id values on the Claim object and wire it up that way but it really is swimming against the current of NHibernate to do so.
Thoughts?
Cheers, --EA
|
|
|
|
|
My guess would be that you're not using TwoWay binding.
|
|
|
|
|
Trying to show enum descriptions in a DataGrid DataGridComboBoxColumn . here's my XAML so far:
<Window.Resources>
<wpfconv:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="accessEnums">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enums:AccessLevel" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
and
<DataGridComboBoxColumn Header="Access"
ItemsSource="{Binding Source={StaticResource accessEnums}, Mode=OneWay}"
SelectedItemBinding="{Binding Access}"
Width="100">
</DataGridComboBoxColumn>
and the enum:
public enum AccessLevel
{
[Description("No Acccess")]
NoAccess = 0,
[Description("Full Acccess")]
HasAccess = 1
}
When I run it I see the enum value in the combo, not the descriptions. Can someone show me how to do this?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
That is clear, because you are not telling the WPF to actually write the Description to the rendering; as I believe, it is just trying to call a simple ToString and then writing what is found there.
For this thread, it is pretty much clear that what you need to do is you need to create a converter for your binding and then read the DescriptionAttribute of the current enum value. Then render that Description in the returning object. You might need to implement the converter, and then add that as an object.
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
I'm trying to extend the WPF dataGrid so I can bind to SelectedItems when SelectionMode = Extended.
First I have this
public class DataGridEx : DataGrid
{
public DataGridEx()
{
this.SelectionChanged += CustomDataGrid_SelectionChanged;
}
public IList SelectedItemsList
{
get { return (IList)GetValue(SelectedItemsListProperty); }
set { SetValue(SelectedItemsListProperty, value); }
}
public static readonly DependencyProperty SelectedItemsListProperty =
DependencyProperty.Register("SelectedItemsList", typeof(IList), typeof(DataGridEx), new PropertyMetadata(null));
private void CustomDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList = this.SelectedItems;
}
}
Then my XAML
<ctrls:DataGridEx x:Name="_ScenariosTable"
Grid.Column="1"
Grid.Row="6"
SelectionMode="Extended"
ItemsSource="{Binding Scenarios}"
SelectedItemsList="{Binding SelectedScenarios, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
and finally my View Model
private List<Scenario> _SelectedScenarios;
public List<Scenario> SelectedScenarios
{
get { return _SelectedScenarios; }
set
{
if (_SelectedScenarios != value)
{
_SelectedScenarios = value;
RaisePropertyChanged("SelectedScenarios");
}
}
}
The binding works because the SETTER is called, yet 'value' is always null.
What's wrong here?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
According to the comments on this StackOverflow answer[^], it should work if you use IList instead of IList<T> in your viewmodel.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That did it! Thanks!
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have this combo box:
<ComboBox Grid.Row="1"
Grid.Column="0"
ItemsSource="{Binding Categories}"
SelectedItem="{Binding SelectedRight.Category}"
IsEnabled="{Binding RightsFieldsEnabled}"
Width="250"
Margin="2"
Style="{StaticResource comboBoxStyle}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Category}"
FontSize="14"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
When a Category is selected is saves it correctly to the Category property of the Right entity. However, when the data is reloaded the correct Category is not selected in the combo.
What am I doing wrong here?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Chances are that your objects and lists are (some sort of) based on the instance properties or fields of the object that is bound. Did you try any static fields here (try making the data source static and then see if that has any effect on reload)?
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
SelectedItem,mode="twoway"
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
No effect
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
You are trying to bind the item attribute to the selected item. Change it to display value and selected item id. Sorry I am on a pad with no vs.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
My enum:
public enum AccessLevel
{
[Description("No Acccess")]
NoAccess = 0,
[Description("Full Acccess")]
HasAccess = 1
}
My Right entity
public class RightEntity : _EntityBase
{
private string _RightName = string.Empty;
public string RightName
{
get { return _RightName; }
set
{
if (_RightName != value)
{
_RightName = value;
RaisePropertyChanged("RightName");
}
}
}
private AccessLevel _Access = AccessLevel.NoAccess;
public AccessLevel Access
{
get { return _Access; }
set
{
if (_Access != value)
{
_Access = value;
RaisePropertyChanged("Access");
}
}
}
}
The view
<Window.Resources>
<wpfconv:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="accessEnums">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enums:AccessLevel" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
and
<ComboBox Grid.Row="7"
Grid.Column="0"
ItemsSource="{Binding Source={StaticResource accessEnums}}"
SelectedItem="{Binding SelectedRight.Access}"
IsEnabled="{Binding RightsFieldsEnabled}"
Width="125"
HorizontalAlignment="Left"
Style="{StaticResource comboBoxStyle}"
Margin="2">
<pre>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}"
FontSize="14"/>
</DataTemplate>
</ComboBox.ItemTemplate>
Problem: When I load the combo list the enum descriptions show fine. I then edit a record and save, then reload the list. I then get an exception in the converter in the Convert method:
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum myEnum = (Enum)value;
string description = GetEnumDescription(myEnum);
return description;
}
Not really sure what's happening. Am I doing this right? Anyone see what's wrong?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Can you try the following code and see if this works?
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(string.IsNullOrEmpty(value as string)) {
Enum myEnum = (Enum)value;
string description = GetEnumDescription(myEnum);
return description;
} else {
}
}
The sh*t I complain about
It's like there ain't a cloud in the sky and it's raining out - Eminem
~! Firewall !~
|
|
|
|
|
Actually, I already did that and it seems to work ok.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Hello,
I am trying to make an app to schedule real life tasks. My main purpose is to learn how to switch between views with commands. Switching between views has partially worked.
My "app" has a main window, with a few buttons(like a horizontal menu bar), and a content control area below the menu buttons, where i display views associated with the buttons.
I managed somehow to make the buttons to switch to my views.
My first 2 views are the "HomeView" and "AddEditView".
In my HomeView i have a listview that is displaying the tasks from my database. On my listview i have attached a contextmenu with 3 options/buttons: Add Task, Edit Task, Remove Task.
I want o make the contextmenu options/buttons to take me to the AddEditView so i can Add/Edit my selected task.
I have tried to bind the contextmenu buttons to the main window buttons and commands, but most likely i did something wrong. I have also tried to link my HomeViewModel with the MainWindowViewModel , but when i am newing up a MainWindowViewModel object in my HomeViewModel i get the following error
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll
pointing to
public TaskLINQToSQLClassesDataContext() :
base(global::DTS.Properties.Settings.Default.TasksConnectionString, mappingSource)
What should i do? Is there other piece of code i should post?
Thanks in advance!
MainWindowViewModel:
public class MainWindowViewModel : INotifyPropertyChanged
{
private HomeViewModel homeVM;
private AddEditViewModel addEditVM;
private NotesViewModel notesVM;
private StatsViewModel statsVM;
private object currentView;
public SwitchViewCommand SwitchToHomeViewCommand { get; private set; }
public SwitchViewCommand SwitchToAddEditViewCommand { get; private set; }
public SwitchViewCommand SwitchToNotesViewCommand { get; private set; }
public SwitchViewCommand SwitchToStatsViewCommand { get; private set; }
public MainWindowViewModel()
{
homeVM = new HomeViewModel();
addEditVM = new AddEditViewModel();
notesVM = new NotesViewModel();
statsVM = new StatsViewModel();
SwitchToHomeViewCommand = new SwitchViewCommand(DisplayHomeView);
SwitchToAddEditViewCommand = new SwitchViewCommand(DisplayAddEditView);
SwitchToNotesViewCommand = new SwitchViewCommand(DisplayNotesView);
SwitchToStatsViewCommand = new SwitchViewCommand(DisplayStatsView);
CurrentView = homeVM;
}
public object CurrentView
{
get { return currentView; }
set { currentView = value; RaisePropertyChanged(); }
}
public void DisplayHomeView()
{
CurrentView = homeVM;
}
public void DisplayAddEditView()
{
CurrentView = addEditVM;
}
public void DisplayNotesView()
{
CurrentView = notesVM;
}
public void DisplayStatsView()
{
CurrentView = statsVM;
}
#region INPC
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
var hndlr = PropertyChanged;
if (hndlr != null)
{
hndlr(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
HomeViewModel:
public class HomeViewModel : BaseViewModel
{
private Models.Task selectedTask;
private string isCompleted;
private ObservableCollection<Models.Task> taskList;
public HomeViewModel()
{
TaskList = new ObservableCollection<Models.Task>(tDC.Tasks);
MwVm = new MainWindowViewModel();
}
public MainWindowViewModel MwVm { get; set; }
public Models.Task SelectedTask
{
get { return selectedTask; }
set
{
if (selectedTask!=value)
{
selectedTask = value;
RaisePropertyChanged();
IsCompleted = selectedTask.Completed == true ? "Completed" : "Not Completed";
}
}
}
public string IsCompleted
{
get { return isCompleted; }
set
{
isCompleted = value;
RaisePropertyChanged();
}
}
public ObservableCollection<Models.Task> TaskList
{
get { return taskList; }
set
{
if (taskList != value)
{
taskList = value;
RaisePropertyChanged();
}
}
}
public void ViewChange()
{
MwVm.SwitchToAddEditViewCommand.Execute(this);
}
}
MainWindowView buttin bindings and conent control:
<StackPanel Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="8" Grid.RowSpan="1" Orientation="Horizontal" HorizontalAlignment="Center" >
<Button x:Name="btnHome" Style="{StaticResource MenuButton}" Content="Home" Grid.Column="1" Grid.ColumnSpan="2" Width="73" Command="{Binding SwitchToHomeViewCommand}">
<Button.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="DodgerBlue" Offset="0.777"/>
<GradientStop Color="#FF9BCF31" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
<Button x:Name="btnAddEdit" Style="{StaticResource MenuButton}" Content="Add/Edit" Grid.Column="2" Grid.ColumnSpan="2" Width="73" Command="{Binding SwitchToAddEditViewCommand}">
<Button.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="DodgerBlue" Offset="0.777"/>
<GradientStop Color="#FF9BCF31" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
<Button x:Name="btnNotes" Style="{StaticResource MenuButton}" Content="Notes" Grid.Column="4" Grid.ColumnSpan="2" Width="73" Command="{Binding SwitchToNotesViewCommand}">
<Button.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="DodgerBlue" Offset="0.777"/>
<GradientStop Color="#FF9BCF31" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
<Button x:Name="btnSettings" Style="{StaticResource MenuButton}" Content="Settings" Grid.Column="6" Grid.ColumnSpan="2" Width="73" Command="{Binding SwitchToStatsViewCommand}">
<Button.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="DodgerBlue" Offset="0.777"/>
<GradientStop Color="#FF9BCF31" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
</Button>
</StackPanel>
<ContentControl Grid.Column="0" Grid.ColumnSpan="8" Grid.Row="2" Grid.RowSpan="6" Content="{Binding CurrentView}" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
HomeView :
<UserControl x:Class="DTS.Views.HomeView"
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:local="clr-namespace:DTS.Views"
mc:Ignorable="d" d:DesignWidth="400" Height="220">
<Grid Margin="0,0,0,-6">
<TextBlock Style="{StaticResource ListviewTitleTxtBlock}" Text="Task List" Margin="10,10,184,196" />
<ListView x:Name="LstVviewTaskList" Height="181" Width="120" Margin="10,35,270,0" VerticalAlignment="Top" VerticalContentAlignment="Top" HorizontalContentAlignment="Left" ItemsSource="{Binding TaskList}" SelectedItem="{Binding SelectedTask,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Task" Background="AliceBlue" Command="{Binding HomeViewModel.SwitchViewAddEditCmd}"/>
<MenuItem Header="Edit Task" Background="AliceBlue" Command="{Binding HomeViewModel.SwitchViewAddEditCmd}"/>
<MenuItem Header="Remove Task" Background="AliceBlue" Command="{Binding HomeViewModel.SwitchViewAddEditCmd}"/>
</ContextMenu>
</ListView.ContextMenu>
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=TaskTitle}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBox Height="20" Margin="140,35,10,171" IsReadOnly="True" Text="{Binding ElementName=LstVviewTaskList, Path=SelectedItem.TaskTitle}"/>
<TextBox Margin="140,61,10,80" IsReadOnly="True" Text="{Binding ElementName=LstVviewTaskList, Path=SelectedItem.TaskDescripion}" />
<Button Content="Mark as completed" FontSize="10" Margin="140,172,13,31" Command="{Binding SwitchViewAddEditCmd}"/>
<TextBlock FontSize="12" Foreground="Black" TextAlignment="Center" Text="{Binding IsCompleted, FallbackValue='Task Completion'}" Margin="140,200,13,10" />
<TextBlock FontSize="12" TextAlignment="Center" Text="{Binding ElementName=LstVviewTaskList, Path=SelectedItem.TaskDate, FallbackValue='Task Date'}" Margin="143,151,10,59" />
</Grid>
</UserControl>
|
|
|
|
|
So, your architecture here has your ViewModels creating instances of each other in the constructor. This is why you are getting a stack overflow. If I were writing this, I would have a parent ViewModel that was responsible for creating this child ViewModels, and use that one to choose which VM was current.
This space for rent
|
|
|
|
|
I will try this.
Thank you!
|
|
|
|
|
Member 12880595 wrote: public MainWindowViewModel()
{
homeVM = new HomeViewModel();
Member 12880595 wrote: public HomeViewModel()
{
...
MwVm = new MainWindowViewModel();
So MainWindowViewModel creates a new HomeViewModel , which creates a new MainWindowViewModel , which creates a new HomeViewModel , which creates...
A classic case of infinite recursion.
Change your code to pass the current MainWindowViewModel instance to each of the child viewmodels:
public MainWindowViewModel()
{
homeVM = new HomeViewModel(this);
addEditVM = new AddEditViewModel(this);
notesVM = new NotesViewModel(this);
statsVM = new StatsViewModel(this);
...
}
...
public HomeViewModel(MainWindowViewModel mwVm)
{
MwVm = mwVm;
...
}
...
public AddEditViewModel(MainWindowViewModel mwVm)
{
MwVm = mwVm;
...
}
...
public NotesViewModel(MainWindowViewModel mwVm)
{
MwVm = mwVm;
...
}
...
public StatsViewModel(MainWindowViewModel mwVm)
{
MwVm = mwVm;
...
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you, it works!
But, how can i make the view change?
Assuming i have a MainWindowViewModel property in each "lower" ViewModel class, should i bind my contextmenu buttons to it, and RaisePropertyChanged, and add a call in the setter to the method i use in the MainViewModel to Display my AddEditView?
|
|
|
|
|
The simplest option is to call the method directly, since it's public:
public void ViewChange()
{
MwVm.DisplayAddEditView();
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I have tried, to call the method, by having a MainWindowViewModel property, and call ViewChangeMethod() in the setter, but it doesnt work;
public HomeViewModel(MainWindowViewModel mwvm)
{
TaskList = new ObservableCollection<Models.Task>(tDC.Tasks);
MwVm = mwvm;
}
public MainWindowViewModel MwVm
{
get { return _mwVm; }
set {if(value != null)
_mwVm = value;
RaisePropertyChanged();
ViewChange();
}
}
<ListView x:Name="LstVviewTaskList" Height="181" Width="120" Margin="10,35,270,0" VerticalAlignment="Top" VerticalContentAlignment="Top" HorizontalContentAlignment="Left" ItemsSource="{Binding TaskList}" SelectedItem="{Binding SelectedTask,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Task" Background="AliceBlue" Command="{Binding MwVm, UpdateSourceTrigger=PropertyChanged}"/>
<MenuItem Header="Edit Task" Background="AliceBlue" Command="{Binding MwVm, UpdateSourceTrigger=PropertyChanged}"/>
<MenuItem Header="Remove Task" Background="AliceBlue" Command="{Binding MwVm, UpdateSourceTrigger=PropertyChanged}"/>
</ContextMenu>
</ListView.ContextMenu>
What should i make sure i checked/have to check, in this case?
If i bind a contextmenu item(located in my HomeView) to a MainWindow Button, and the command associated with it, should i specify the datacontext in xaml?
|
|
|
|
|