I have a bit of a strange case. The issue is that I have 3 radiobuttons and they are binded to the EffectiveValue property of my viewmodel.
<StackPanel Grid.Column="2" Orientation="Horizontal" Margin="5,0,0,0">
<StackPanel.Visibility>
<MultiBinding Converter="{StaticResource MultiBoolToVisibilityHidden}">
<Binding Path="IsSelected" RelativeSource="{RelativeSource AncestorType=telerik:RadListBoxItem}"/>
<Binding Path="Criterion.IsOverridable"/>
<Binding Path="DataContext.CanOverrideEvaluation" ElementName="ThisInformationControl"/>
</MultiBinding>
</StackPanel.Visibility>
<telerik:RadRadioButton Content="Y" IsChecked="{Binding EffectiveValue, Converter={StaticResource EnumToBool}, ConverterParameter={x:Static utilities:Ternary.TRUE}, Mode=OneWay}" Style="{StaticResource EmptyRadioButtonStyle}"
Command="{Binding OverrideValueCommand}" CommandParameter="{x:Static utilities:Ternary.TRUE}" Margin="2,1" Width="16" VerticalAlignment="Center"/>
<telerik:RadRadioButton Content="?" IsChecked="{Binding EffectiveValue, Converter={StaticResource EnumToBool}, ConverterParameter={x:Static utilities:Ternary.UNKNOWN}, Mode=OneWay}" Style="{StaticResource EmptyRadioButtonStyle}"
Command="{Binding OverrideValueCommand}" CommandParameter="{x:Static utilities:Ternary.UNKNOWN}" Margin="2,1" Width="16" VerticalAlignment="Center"/>
<telerik:RadRadioButton Content="N" IsChecked="{Binding EffectiveValue, Converter={StaticResource EnumToBool}, ConverterParameter={x:Static utilities:Ternary.FALSE}, Mode=OneWay}" Style="{StaticResource EmptyRadioButtonStyle}"
Command="{Binding OverrideValueCommand}" CommandParameter="{x:Static utilities:Ternary.FALSE}" Margin="2,1" Width="16" VerticalAlignment="Center"/>
</StackPanel>
The problem is this. Say my ViewModel Effective Value is 'Y'. I click the 'N' button. But then based on certain conditions, I do not actually set the EffectiveValue to 'N' and it remains 'Y'. The problem I am having is now the 'N' looks selected even though the viewmodel still says that the value is 'Y'. What can I do to make sure my radiobuttons strictly listen to the viewmodel's value?
My current workaround it to force a property changed on the effective value but I feel this is kind of a hack.
Thanks
I think the answer lies with your radio button bindings. Notice that you have them set to OneWay, but you said that based on certain conditions you keep the value as 'Y'. How does the WPF control know that you've rejected the UI change?
I suggest changing the binding Mode to TwoWay and maybe also include UpdateSourceTrigger=PropertyChanged in the bindings. Then your code behind and the UI can communicate "two ways" to each other about what the appropriate state of the radio button should be.
Related
I have two controls in a grid.
<TextBlock Text="{Binding Name}" TextAlignment="Center" />
<TextBox Visibility="{Binding ElementName=EditMode,Source={Binding RelativeSource=
{RelativeSource FindAncestor, AncestorType={x:Type Window}}},
Converter={StaticResource BoolToVis}}" Text="{Binding Name}"
TextAlignment="Center" />
I am trying to implement something like an editable/non editable behaviour. I know i might choose for a TextBox and simply change the IsEditable property but still, in my scenarion i would need to DataContext, at least that's what i am thinking of.
In my example, the TextBlock works fine, and the Text property on the TextBox also works fine but for the Visibility part, i want to bind to a data property ( EditMode which is a boolean) found on some other layer. Is there a way to change the DataContext to that, but only for the Visibility ? The Text property should remain as it is now.
Should i try a hack, to define an invisible checkbox, change IsChecked when my Edit button is clicked and bind directly to that ? I will try this. I think this way, no DataContext changing is needed.
#FrumRoll is correct that you can access a property that is not in the set DataContext object using a RelativeSource Binding. However, I'm not sure that their code is quite right... try this:
<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource
AncestorType={x:Type YourXamlPrefix:MainWindow}}}, Converter={StaticResource
BoolToVis}}" Text="{Binding Name}" TextAlignment="Center" />
Clearly, you'll need to change the YourXamlPrefix value with your local XAML Namespace Prefix and MainWindow with the name/type of your Window if it is not called MainWindow. This also assumes that your EditMode property has been defined in that Window.
This may also work, but is not specifically looking for your exact Window, so may have some problems:
<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource
AncestorType={x:Type Window}}}, Converter={StaticResource BoolToVis}}"
Text="{Binding Name}" TextAlignment="Center" />
It seems to me you were almost there, you should be able to use a RelativeSource to do this. The issue is that you misused ElementName, ElementName is to bind to a property of a named source and would be used instead of RelativeSource. What you meant to use was Path, which is optional as seen below.
<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource AncestorType={x:Type Window}},
Converter={StaticResource BoolToVis}}"
Text="{Binding Name}" TextAlignment="Center" />
I'm trying to get a multi-bound listbox to call the convert back method when items inside it change. Specifically I have a datatemplate that maps each entry to a checkbox and I'd like the source to be updated whenever a box is checked.
<ListBox x:Name="listBoxEdit" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" Height="100" >
<ListBox.ItemsSource>
<MultiBinding Converter="{StaticResource selectedLoadsConverter}" >
<Binding Path="AvailableLoads"/>
<Binding Path="CurrentUnit"/>
</MultiBinding>
</ListBox.ItemsSource>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Item1}" IsChecked="{Binding Item2}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I know the problem lies in the fact that I'm binding to to the ItemsSource property which is never actually being updated by the checkbox changing, but I can't figure out a good way to push the updates up to the source.
I want to know if there is option that when I type into a text box or drag to anything (I'm using D&D functionality), the text on it will automatically insert brackets. I don't want to do that on the logic or in the code beyond just in the ui. Is that posible?
For example: if I type AAA, I will see in the text box (AAA).
I dont want to do that on the logic or in the code beyond
By your conditions it is not possible. Something has to capture the change event and add the brackets to the text. That something is not possible without logic as found in code behind.
The options are
Subscribe to the textblock's SelectionChange event and add the brackets.
Create a custom control which does #1 internal so the consumer doesn't have to do it. (By a technicality it answer's your question).
Put the textblock control between two labels which have the brackets as their context. Bind their visibility to a Boolean on the VM which reports when the bound data of the textblock has changed. If there is text then they become visible, if there is no text it is hidden. Downside is that this is not caught as the user types or until it fully changed, only when exiting the control.
Here is #3
<Label Content="(" Visibility="{Binding HasText, Converter={StaticResource WindowsVisibilityBooleanConverter}}" />
<TextBox Text="{Binding TextInput}"
Height="18"
HorizontalAlignment="Stretch" />
<Label Content=")" Visibility="{Binding HasText, Converter={StaticResource WindowsVisibilityBooleanConverter}}" />
Without any of your own logic code, I suppose this is the closest thing to what you want.
<TextBox x:Name="tbInput" />
<TextBlock Text="{Binding ElementName='tbInput', Path=Text, StringFormat={}({0})}" />
The downside would be that you'll always see the empty brackets () if the TextBox is empty.
See: String format using MultiBinding?
<StackPanel>
<Slider x:Name="sl1" Minimum="10" Maximum="100"/>
<Slider x:Name="sl2" Minimum="10" Maximum="100"/>
<Label x:Name="label13" Background="Yellow" Foreground="Black">
<Label.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} x {1} Test">
<Binding ElementName="sl1" Path="Value" />
<Binding ElementName="sl2" Path="Value" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Label.Content>
</Label>
</StackPanel>
I have an itemscontrol that is bound to a collection of objects.
in the data template, i bind an action that is to be used by all of the controls created if their focus is lost.
In the control, there is a textbox so if there are 1 items in the item controls ItemSource, there will be 2 textboxes.
Now, if Textbox 1 has focus and I click somewhere besides Textbox 2, the action is executed once (because the focus was lost). But if I click in Textbox 2, the action is executed twice. Why?
<ItemsControl Grid.Row="1" Margin="0,5,0,5" ItemsSource="{Binding
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, Path=Collection}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type ct:CollectionItem}">
<cc:TestControl
ValueChangedAction="{Binding
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, Path=ValueChangedAction}"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This is the Control.
<ewt:DecimalUpDown Tag="{Binding Uid}" Grid.Row="0" Grid.Column="3"
HorizontalAlignment="Stretch" TextAlignment="Left" Margin="10,5,10,5"
FormatString="C2" ShowButtonSpinner="False" VerticalAlignment="Center"
Value="{Binding Value}" LostFocus="DecimalUpDown_LostFocus" />
The bound action is executed in this event handler.
If your action is supposed to update the source of the binding (e.g. the Window, it looks like from your example), you might want to try adding OneWayToSource to your Binding so that binding only occurs one way—from the textbox to whatever it's bound to.
I am working on a Silverlight application which makes an extensive use of Prism, the MVVM pattern and MEF. For several reasons, I have chosen to follow a View-first approach.
In one of the Views there is a DataGrid, and one of the columns of this grid is a DataGridTemplateColumn, which has just a Button.
I'd like to define both a Command and a CommandParameter on the Button. The Command should be a DelegateCommand of the ViewModel. CommandParameter should be the SelectedItems list coming straight out of the dataGrid.
I've tried several approaches to do this, but either Command or CommandParameter are null.
It follows the code that I originally wrote:
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Width="15" Height="15" Content=">"
Command="{Binding UpdateSearchParametersCommand}"
CommandParameter="{Binding SelectedItems, ElementName=dataGrid}">
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
Could someone advice me on what the best way to go about it is?
Thanks in advance,
Gianluca.
Your current binding is pointing to DataGridRowItem.UpdateSearchParametersCommand. You need to change it to point to DataGrid.DataContext.UpdateSearchParametersCommand
<sdk:DataGrid x:Name=dataGrid>
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Width="15" Height="15" Content=">"
Command="{Binding DataContext.UpdateSearchParametersCommand, ElementName=dataGrid}"
CommandParameter="{Binding SelectedItems, ElementName=dataGrid}">
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid>
If you bind your DataGrid using ItemsSource, then Command and CommandParameter binding is associated to the current item - the way you've written.
You should use alternative source in this case. Command should be binded to the DataContext.UpdateSearchParametersCommand and CommandParameter - to DataContext.SelectedItems.
In your case neither UpdateSearchParametersCommand, nor SelectedItems cannot be found in the binded item.
UPDATED
Be sure to set the right type for ancestor. I've set it to window, but maybe you are using UserControl.
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Width="15" Height="15" Content=">"
Command="{Binding Path=DataContext.UpdateSearchParametersCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
CommandParameter="{Binding Path=DataContext.SelectedItems, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
In silverlight 5 you can do this
<Button Command="{Binding Path=DataContext.PreviewPublishCommand, RelativeSource={RelativeSource AncestorType=controls:ChildWindow}}" Content="Publish" />
Just adjust AncestorType to be whatever your top level element is (UserControl, ChildWindow, etc).
Many of you tried to help me out on this. Thank you for that.
Unfortunately the provided answers were mostly relative to WPF.
Here is how I've solved the problem:
<helpers:BindingHelper.Binding>
<helpers:BindingList>
<helpers:RelativeSourceBinding TargetProperty="Command" Path="DataContext.ToggleDataArchiveInheritanceCommand" RelativeMode="FindAncestor" AncestorType="ChildWindow" />
</helpers:BindingList>
</helpers:BindingHelper.Binding>
Ok, this comes from another point of the same application, but the principle is the same.
If a binding is defined inside a , the only way you have in Silverlight to reach out other elements that normally would be out-of-scope (as they are not part of the DataTemplate) is to walk through the xaml object tree. That's what the BindingHelper does.
Posting here as I hope the information will be useful to someone else.
Cheers,
Gianluca