|
It's probably being overridden by the binding.
Changing the Text property to create a watermark isn't really a good idea. Try one of the other solutions from this SO thread[^], or this GitHub project[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I already saw the SO one. Not really a god idea either. It contains two textboxes and just hides either one.
The GitHub solution seems right.
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 a DataGrid bound to an ObservableCollection<myclass>. MyClass has a Name property on it. The model implements INotifyPropertyChanged.
When in the grid the user changes a Name value on any row the selected row'a Name property on the model is updated.
How can I know in ViewModel that a model bound to a data grid has changed?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I trap the Cell Edit End event with:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<telerik:RadTreeListView x:Name="tvData">
<i:Interaction.Triggers>
<i:EventTrigger EventName="CellEditEnded">
<i:InvokeCommandAction Command="{Binding TKCellEndEdit}" CommandParameter="{Binding CurrentCell,RelativeSource={RelativeSource AncestorType=telerik:RadTreeListView}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Viewmodel
public ICommand TKCellEndEdit { get; set; }
TKCellEndEdit = new DelegateCommand<object>(this.tKCellEndEdit);
private void tKCellEndEdit(object o)
{
string s = o.ToString();
GridViewCell oCell = (o as GridViewCell);
if (oCell.Value != null)
{
if (oCell.DataContext.GetType() == typeof(TreeNodeDE))
{
}
}
While that is for a telerik treelistview it is the same code for a gridview just changing the control.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
If the model implements INPC, your VM can hook into that and receive the notification when the Name changes. It doesn't need to get any more complicated than that.
This space for rent
|
|
|
|
|
I'm not sure I understand. Are you referring to listening to the INPC event in the VM? What would that look like?
Maybe something like this?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
It's fairly straightforward to do. Hook up to the CollectionChanged event handler from your ObservableCollection and then, whenever the collection changes, you add or remove event handlers. The event handling looks a bit like this:
private void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (object item in e.OldItems)
{
((INotifyPropertyChanged)item).PropertyChanged -= MyPropertyChangedHandler;
}
}
if (e.NewItems != null)
{
foreach (object item in e.NewItems)
{
((INotifyPropertyChanged)item).PropertyChanged += MyPropertyChangedHandler;
}
}
} This means, whenever you add or remove an item to your collection, you now have the ability to hook into the models INPC chain. This might look a bit like this:
private void MyPropertyChangedHandler(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != "Name") return;
MyModel model = sender as MyModel;
Debug.WriteLine($"Name changed to {model.Name}");
}
This space for rent
|
|
|
|
|
Ouch - I do that for a single item on the selectedobject property change, never considered it for an entire collection.
I almost never allow inline editing of grid data, the odd checkbox or single cell is handle by the celleditend event.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I have to admit, I've never been the biggest fan of inline editing. I generally prefer to look at other methods of editing grid data, such as through the use of dialog boxes. Saying that, the approach I outlined here is simple enough to do (although I tend to use RX to watch collection and property changes).
This space for rent
|
|
|
|
|
Hi Guys, I have created a WPF Application which needs to run forever, so, I want to disable closing of application from task manager. I applied some code, and in apps section in task manager, I am able to disable closing of application, but when I close it from background processes in task manager then close it from apps section, it does not get restarted and get closed.
So, Is there any way by which I can restart my application once it gets closed from background processes in Task Manager or any other method to do this operation. Any help would be greatly appreciated. Please suggest.
|
|
|
|
|
About the only thing you could realistically do is have a service running that monitors the status of the application and then fires it off if it's been killed off. The service would have to periodically poll the application to determine whether or not the app was running (it would also have to take into account whether the app was closed because the computer was shutting down).
This space for rent
|
|
|
|
|
I have created a RadioButton who's style will look similar to this. In my version the line can be top, left, right, or bottom.
In the code behind I did:
public class MaroisRadioButton : RadioButton
{
public enum Position
{
Bottom,
Left,
Right,
Top
}
#region DP RadioMarkPosition
public static readonly DependencyProperty RadioMarkPositionProperty =
DependencyProperty.Register("RadioMarkPosition",
typeof(Position),
typeof(MaroisRadioButton),
new PropertyMetadata(Position.Left));
public Position RadioMarkPosition
{
get { return (Position)GetValue(RadioMarkPositionProperty); }
set { SetValue(RadioMarkPositionProperty, value); }
}
#endregion
#region DP RadioMarkSize
public static readonly DependencyProperty RadioMarkSizeProperty =
DependencyProperty.Register("RadioMarkSize",
typeof(double),
typeof(MaroisRadioButton),
new PropertyMetadata(null));
public double RadioMarkSize
{
get { return (double)GetValue(RadioMarkSizeProperty); }
set { SetValue(RadioMarkSizeProperty, value); }
}
#endregion
}
Then I created style for it and in the style I want to bind the RadioMarkSize to the Width property in the XAML:
<Border Grid.Row="1"
Grid.Column="0"
Margin="2"
Background="{DynamicResource buttonPressedBackBrush}"
Width="{Binding RadioMarkSize}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Name="LeftRadioMark"/>
But I can't get the binding to work. I get a binding error "BindingExpression path error: 'RadioMarkSize' property not found on 'object' ''MainWindowViewModel'"
How do I bind the Width property to the DP in the code behind?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
The DependencyProperty is on a derived RadioButton and you're attempting to read it on a Border bound to the VM DataContext. That's why your code can't see it. Why not put your derived RadioButton on there and get access to the DPs from that?
|
|
|
|
|
Here's the full style. The Border is part of the RadioButton Control Template's BulletDecarator:
<Style x:Key="BlockRadioButtonStyle"
TargetType="{x:Type mbc:MaroisRadioButton}"
BasedOn="{StaticResource BaseRadioButtonStyle}">
<pre>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type mbc:MaroisRadioButton}">
<BulletDecorator Cursor="Hand">
<Border BorderBrush="LightGray"
BorderThickness="2"
Margin="2">
<Grid>
<Border Grid.Row="1"
Grid.Column="0"
Margin="2"
Background="{DynamicResource buttonPressedBackBrush}"
Width="{Binding RadioMarkSize}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Name="LeftRadioMark"/>
<ContentPresenter Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="2"/>
</Grid>
</Border>
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Try using TemplateBinding instead.
<Border
Grid.Row="1"
Grid.Column="0"
Margin="2"
Background="{DynamicResource buttonPressedBackBrush}"
Width="{TemplateBinding RadioMarkSize}"
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Name="LeftRadioMark"
/>
TemplateBinding Markup Extension | Microsoft Docs[^]
"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! ya learnt me something
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Did you set the DataContext to your custom create class called "MaroisRadioButton" I believe in the code-behind you need to set the DataContext to this custom class so XAML engine can locate this custom dependency property.
Ben Scharbach
Temporalwars.Com
YouTube:Ben Scharbach
|
|
|
|
|
I created a UserControl with some buttons called 'ButtonBarView'. They buttons all like this:
<mctrls:MaroisImageButton Grid.Row="0"
Grid.Column="0"
Caption="New"
Style="{StaticResource NewButtonStyle}"
Command="{Binding NewCommand}"
Margin="3"/>
The control is then placed on a view which has an ICommand on it called NewCommand, yet the binding fails. The Output window shows
BindingExpression path error: 'NewCommand' property not found on 'object' ''ButtonBarView' (Name='')'. BindingExpression:Path=NewCommand; DataItem='ButtonBarView' (Name=''); target element is 'MaroisImageButton' (Name=''); target property is 'Command' (type 'ICommand')
I thought that as long as the command exists on the VM the control would find it. What am I doing 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.
|
|
|
|
|
It's already told you what is wrong in the error. It thinks that the DataContext is set to the view, not the VM.
|
|
|
|
|
Ya I had this.DataContext = this in the code behind.
I'm a dumbass
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
I have a UserControl that contains a ListBox, a CheckBox, a TextBox, and OK & Cancel buttons. I made a few small changes to the button's control template to change the button's border and added a trigger.
This control can be used an any app, so I need to understand how to style it. Would I need to name the button and create a named style? That would be in each app that I want to use it I would have to create style elements that specifically target each element in my UserControl.
I'm not sure how styling works for generic UserControls. Can someone point me in the right direction?
Thanks
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
 In this WPF can be a real pain. I wanted to create a textbox that had a browse button inside of it to match some other controls and it was quite the hassle. Basically, the flow is this:
1. Create your user control, hopefully it is based off of other controls so you can use the existing dependency properties
2. In your resources.xaml file, add a reference to the xmlns of your control
3. Add style in resources.xaml
For me, my control is called a BrowseTextBox. The style looks like this:
<Style x:Key="{x:Type cont:BrowseTextBox}"
TargetType="{x:Type cont:BrowseTextBox}"
BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Background"
Value="#FFFFFF" />
<Setter Property="Foreground"
Value="#000000" />
<Setter Property="Padding"
Value="5,3" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="KeyboardNavigation.TabNavigation"
Value="Once" />
<Setter Property="KeyboardNavigation.ControlTabNavigation"
Value="Cycle" />
<Setter Property="IsTabStop"
Value="False" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cont:BrowseTextBox}">
<Grid x:Name="LayoutGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="TextColumn"
Width="*" />
<ColumnDefinition x:Name="ButtonsColumn"
Width="Auto" />
</Grid.ColumnDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Duration="0"
To="1"
Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="MouseOverVisual" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="Focus">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
Background="{TemplateBinding Background}"
Grid.ColumnSpan="2" />
<Border x:Name="MouseOverVisual"
BorderThickness="1"
BorderBrush="{StaticResource TextBoxFocus}"
Background="{TemplateBinding Background}"
Grid.ColumnSpan="2"
Opacity="0" />
<Border x:Name="Focus"
BorderBrush="{StaticResource TextBoxFocus}"
BorderThickness="{TemplateBinding BorderThickness}"
Grid.ColumnSpan="2"
IsHitTestVisible="False"
Visibility="Collapsed" />
<Border x:Name="ReadOnly"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
Background="#FF575859"
Grid.ColumnSpan="2">
<Border.Visibility>
<Binding Path="IsReadOnly"
RelativeSource="{RelativeSource TemplatedParent}">
<Binding.Converter>
<telerik:BooleanToVisibilityConverter />
</Binding.Converter>
</Binding>
</Border.Visibility>
</Border>
<ScrollViewer x:Name="PART_ContentHost"
Grid.Column="0"
BorderBrush="Transparent" />
<Border x:Name="PART_SearchIconBorder"
Grid.Column="1"
BorderThickness="0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<telerik:RadButton x:Name="Search"
Style="{StaticResource TextButton}"
Content="..."
ToolTip="Browse"
VerticalAlignment="Stretch"
Width="15" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Mine is using some Telerik styles as that is what I am using on the rest of my form. The control in the view looks like this:
<cont:BrowseTextBox x:Name="CurrentObservation_FilePath"
Grid.Row="7"
Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="2,2,0,0"
Browse="FileBrowser_OnClick" />
The user control is pretty much just the same thing you are talking about, an existing type of control (text box) with another control (button) inside of it.
|
|
|
|
|
Using MVVM I have a property to hold the value to be displayed in the ColumnGroup Text property
This fails to display the required text
<telerik:GridViewColumnGroup Name="ThisYearA" Header="{Binding Path=DataContext.lThisYearActual, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type telerik:RadGridView}}}" />
I have also bound the text to a hidden textblock, this also fails to display in the ColumnGroup
<telerik:GridViewColumnGroup Name="ThisYearF" Binding ElementName=txtLastYearActual}" />
Any suggestion as to how to bind this?
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
|
I have created a split button that looks and works like one of these. I put it up OneDrive.
I've never really done anything like this before, and I'd like to create a suite of controls. I've already created a DropDown Date/Time Picker. Now I have this done.
So for this control, use it like this:
xmlns:sb="clr-namespace:Marois.Framework.WPF.Controls.SplitButtonControl;assembly=Marois.Framework.WPF.Controls"
<sb:SplitButton Grid.Column="5"
Height="25"
Width="150"
Items="{Binding ElementName=myWindow, Path=MyItems}"
SelectedItem="{Binding ElementName=myWindow, Path=MySelectedItem, Mode=TwoWay}"
SelectedItemChanged="SplitButton_SelectedItemChanged" />
and in the code behind
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private List _MyItems;
public List MyItems
{
get { return _MyItems; }
set
{
if (_MyItems != value)
{
_MyItems = value;
RaisePropertyChanged("MyItems");
}
}
}
private SplitButtonItem _MySelectedItem;
public SplitButtonItem MySelectedItem
{
get { return _MySelectedItem; }
set
{
if (_MySelectedItem != value)
{
_MySelectedItem = value;
RaisePropertyChanged("MySelectedItem");
}
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
MyItems = new List
{
new SplitButtonItem(new BitmapImage(new Uri(@"left_arrow.png")), "Item 1"),
new SplitButtonItem(null, "Item 2"),
new SplitButtonItem(new BitmapImage(new Uri(@"right_arrow.png")), "Item 3"),
};
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void SplitButton_SelectedItemChanged(object sender, SplitButtonControl.SplitButton.SelectionChangedEventArgs e)
{
MessageBox.Show(e.SelectedItem.Caption, "Selected Item", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
So here's the question. If you look at the XAML for the control you'll see two Templates - one for the Button portion and another for the ToggleButton. They contain various settings for colors, brushes, margins, CornerRadius, etc.
How do you create a style for this? Would you name each element and then create a style that targets each named element?
How do you create a suite of controls, then create style(s) that apply across all your controls?
Thanks!
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|