I am writing small project to learn MVVM WPF. In the project I am opening with a button dialog window with form to fill up. The form has 2 TextBoxes
, that I want to have them empty every time the dialog window is opened again.
In StackOverflow is a lot of examples where TextBox is binded to methods that they are cleaning TextBox with .Clear();
or string.Empty;
or .Text=""
; etc.
The problem is, that my TextBoxes are already MultiBinded
to the converter method used with the form.
<local:CustomContentDialogBox.CommandParameter>
<MultiBinding Converter="{StaticResource newPerson}">
<Binding ElementName="tbID" Path="Text"/>
<Binding ElementName="tbFirstName" Path="Text"/>
<Binding ElementName="tbSecondName" Path="Text"/>
<Binding ElementName="cbHeight" Path="Text" />
</MultiBinding>
</local:CustomContentDialogBox.CommandParameter>
As far as I experienced, I was not able to bind it from the texbox by itself again like that:
<TextBox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2"
x:Name="tbFirstName"
FontSize="20"
Margin="10,0,0,0"
Background="#F5F5F5"
TextAlignment="Left"
Text="{Binding ClearMyBoxPlease}"
HorizontalAlignment="Left" Height="30" Width="150"/>
After all day research I figured out, that I can just add to the button in dialog window Click="Button_Click" and clean text boxes in code behind.
<Button Grid.Row="0" Grid.Column="3"
VerticalAlignment="Top"
Margin="5,5,5,5"
Height="30" Width="80"
FontSize="20"
Background="#ccffe1"
Content="Add"
Click="Button_Click"
local:CustomContentDialogBox.CustomContentDialogResult="True">
</Button>
Code behind, where I want clean up only 2 text boxes:
private void Button_Click(object sender, RoutedEventArgs e)
{
tbFirstName.Text = "";
tbSecondName.Text = "";
}
For your reference, my converter class, that takes TextBoxes from MultiBinding:
public class PersonConverter : IMultiValueConverter
{
HeightListToString pzts = new HeightListToString();
public object Convert(object[] values, Type targetType, object parameter,
CultureInfo culture)
{
string id = (string)values[0];
string firstName = (string)values[1];
string secondName = (string)values[2];
Model.HeightList heightList = (Model.HeightList)pzts.ConvertBack(
values[3], typeof(Model.HeightList), null, CultureInfo.CurrentCulture);
return new ViewModel.PersonsList(id, firstName, secondName, heightList);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
CultureInfo culture)
{
throw new NotImplementedException();
}
}
Also I was trying to use ICommand
in my ViewModel class and bind it with TextBox. Even if the syntax is wrong, the program was not walking through break points on it:
private ICommand clearMyBoxPlease;
public ICommand ClearMyBoxPlease
{
get
{
clearMyBoxPlease = new RelayCommand(
argument =>
{
TextBox tb = (TextBox)argument;
tb.Clear();
}
);
return clearMyBoxPlease;
}
}
My point is, that it is only one code behind that gave me proper effect. The question, is my code against MVVM pattern theory? If yes, what solution should I use? Thanks in advance.
UPDATE:
I just tryed:
<TextBox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2"
x:Name="tbFirstName"
FontSize="20"
Margin="10,0,0,0"
Background="#F5F5F5"
TextAlignment="Left"
HorizontalAlignment="Left" Height="30" Width="150">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotLost">
<i:InvokeCommandAction Command="{Binding ClearMyTextPlease}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
with command:
public ICommand ClearMyTextPlease
{
get
{
if (clearMyTextPlease == null)
clearMyTextPlease = new RelayCommand(
argument =>
{
TextBox tb = (TextBox)argument;
tb.Text = string.Empty;
}
);
return clearMyTextPlease;
}
}
It still does not go through breakpoints on ClearMyTextPlease
.
Ok, just for the future reference. I solved my problem with clearing TextBoxes in my dialog window from VM.
Still I was not able to bind my Text to the property, probably I did something wrong, but I used VisualTreeHelper and called the method before closing the window.
Method:
static public void TraverseVisualTree(Visual myMainWindow)
{
int childrenCount = VisualTreeHelper.GetChildrenCount(myMainWindow);
for (int i = 0; i < childrenCount; i++)
{
var visualChild = (Visual)VisualTreeHelper.GetChild(myMainWindow, i);
if (visualChild is TextBox)
{
TextBox tb = (TextBox)visualChild;
tb.Clear();
}
TraverseVisualTree(visualChild);
}
}
Calling in dialg window class in VM:
public CustomContentDialogBox()
{
execute =
o => //parametr "o" wyrażenia lambda
{
if (window == null)
{
window = new Window();
window.Width = WindowWidth;
window.Height = WindowHeight;
if (Caption != null) window.Title = Caption;
window.Content = WindowContent;
//(some logic)
TraverseVisualTree(window);
window = null;
}
};
}