How do I create a custom four button control with useful bindings? - c#

I am trying to make a clicker game in WPF based on CivClicker Mostly just a clone right now but... I hope to expand on the concept in the future.
It is mostly to practice and explore more complex MVVM and xaml problem solving. As you can see in the link, there are a lot of repeating buttons and I want to streamline that somehow.
My current solution is garbage but it is somewhat working. It started as a one command per unique button, not very clean. Then, with the CommandParameter, I cut down the commands to one per building object and had the CommandParameter take the number of buildings I wanted to purchase, a bit more clean. In my current iteration, I only have one command for all of purchase buttons related to the buildings. I am using Multibinding to bind static buildingtype and the amount of buildings to purchase.
My current 4 button purchase mechanic looks like this.
<StackPanel Orientation="Horizontal">
<Button Command="{Binding BuyTentCommand}" Content="Build Tent" Width="120" ToolTip="2 skins, 2 wood: +1 max pop.">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MConverter}">
<Binding Source="1"/> //Amount of buildings
<Binding Source="0"/> //Building ID
</MultiBinding>
</Button.CommandParameter>
</Button>
<Button Command="{Binding BuyTentCommand}" Content=" x10 " Margin="2,0">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MConverter}">
<Binding Source="10"/>
<Binding Source="0"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
<Button Command="{Binding BuyTentCommand}" Content=" x100 " Margin="2,0">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MConverter}">
<Binding Source="100"/>
<Binding Source="0"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
<Button Command="{Binding BuyTentCommand}" Content=" x1000 " Margin="2,0">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MConverter}">
<Binding Source="1000"/>
<Binding Source="0"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
</StackPanel>
Repeating that piece of code 16 times(or more), is not really ideal in any scenario. If anyone can show me an working example on how to make something like this in to a single reusable UserContol or something, I will be very grateful.
I edited my question to be a bit more generic/conceptual.
BTW, first code-post ever on here and please be lenient and I would appreciate any and all suggestions for improvements on the post format.

Related

How do I write inline xaml for a MultiBinding converter?

How do I include the second binding? Where do the brackets and commas go?
There are five thousand examples that show how to do it in xml but nothing about how this should appear inline.
NOT THIS
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:F1}{1:F1}">
<Binding Path="A" />
<Binding Path="B" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
THIS
<StackPanel Grid.Column="0"
Orientation="Vertical"
HorizontalAlignment="Left"
Visibility="{MultiBinding Converter={StaticResource multi_bool_vis_conv},
Bindings={Binding LabelFormat.HasLotMaskShiftCode}}">
I need to pass a second binding LabelFormat.HasSomeOtherCode. How do I include that second binding?
Assuming multi_bool_vis_conv implements the interface IMultiValueConverter and you handle the different parameters by indexing off of the value array, the binding should look like this:
<MultiBinding Converter="{StaticResource YourConverter}">
<Binding Path="YourProperty1"/>
<Binding Path="YourProperty2"/>
</MultiBinding>
I assume you want this on one line ("in-line") because you want to set the binding on the StackPanel's Visiblity property and your not sure how to do that in a multi-line way...
You can break it out like this:
<StackPanel>
<StackPanel.Visibility>
<MultiBinding Converter="{StaticResource YourConverter}">
<Binding Path="YourProperty1" />
<Binding Path="YourProperty2" />
</MultiBinding>
</StackPanel.Visibility>
</StackPanel>
The only other way I can see to do what you want is to roll your own StackPanel and include dependency properties for each of the bindings you want. You can then bind each of those on their own line and forgo a binding on the Visibility property all-together, instead opting to control the visibility in the code-behind of your custom control.

How to Show Two textBox control content in third one using concatenating in WPF only in xaml binding no viewmodel code & code behind code

How to Show Two textBox control content in third one using concatenating in WPF only in xaml binding no viewmodel code & code behind code.
Something like this should do the trick.
<TextBlock>
<Run Text="{Binding Path=Text, ElementName=txt1}"/>
<Run Text="{Binding Path=Text, ElementName=txt2}"/>
</TextBlock>
Where the ElementName property is the Name of your TextBoxes.
If you do not want a space between the runs, then put them on the same line like this.
<TextBlock>
<Run Text="{Binding Path=Text, ElementName=txt1}"/><Run Text="{Binding Path=Text, ElementName=txt2}"/>
</TextBlock>
EDIT:
Sorry just re-read the question, and believe you want the output to be in another TextBox. TextBoxes do not support the Run object so you have to approach this with a MultiBinding.
<TextBox>
<TextBox.Text>
<MultiBinding StringFormat="{}{0}{1}">
<Binding Path="Text" ElementName="txt1" />
<Binding Path="Text" ElementName="txt2" />
</MultiBinding>
</TextBox.Text>
</TextBox>
Hopefully this helps!

Binding the Value of StringFormat

I have a Textbox with a Value and a Unit bound like this:
<TextBox Text="{Binding Path=Value,StringFormat='{}{0} mm'}" />
The Unit mm should be also bound to the ViewModel Property Unit. This can be done via a Multibinding:
<TextBox>
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Value"
Mode="TwoWay" />
<Binding Path="Unit"
Mode="OneWay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
But with this I lose my Two Way Binding and I don't want to edit the Unit aswell. If ths user deletes "8 mm" and enteres an "8" the binding should automatically reevaluate the binding and add the unit as it is done via normal string format binding.
So finally I need something like this:
<TextBox>
<TextBox.Text>
<Binding Path="Value"
StringFormat="{Binding Path=ValueUnitStringFormat}" />
</TextBox.Text>
</TextBox>
But unfortunally StringFormat Property on BindingBase is not a DependencyProperty.
Anyone got a solution for this?

multi binding in wpf

I am trying to do multiple binding in wpf.
here is my code:
<CheckBox>
<CheckBox.IsChecked>
<MultiBinding Converter="{View:MultiConvertorOr}">
<Binding ElementName="txtbox1" Path="Text" Converter="{View:TextToBool}" Mode="TwoWay">
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListBoxItem}}" Path="IsSelected" Mode="TwoWay">
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
My goal is when I enter text I want the checkbox to be checked (what happens) and the listBoxItem to be selected. (this part is not working).
I also want to keep the binding between the itemListBox and the checkBox (this also works).
Any Ideas how can I do what I want? maybe with event triggers or something like it?
Thanks ahead.

How to use MultiBinding many times, in abbreviated form, each with different ConverterParameter?

I have a IMultiValueConverter called Placer, being use like this:
<Rectangle Name="HostBox" Fill="#FFF4F4F5" Height="36" Stroke="Black" Canvas.Top="32"
Width="86" RadiusY="9.5" RadiusX="9.5">
<Canvas.Left>
<MultiBinding Converter="{StaticResource Placer}" ConverterParameter="0.5">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource AncestorType={x:Type Canvas}}"/>
<Binding Path="Width" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Canvas.Left>
</Rectangle>
But I have many Rectangles, on which I want to apply the same logic, but with different ConverterParameter value. Do I have to include this not-so-small snippet under each Rectangle's Canvas.Left attached property? (rhetorical question... obviously there's a smarter way... but how?)
Try using a style. For instance, the following one is applied to all the rectangle instances but you could also give it a key and apply it individually to your rectangles:
<Style TargetType="Rectangle">
<Setter Property="Canvas.Left">
<Setter.Value>
<MultiBinding Converter="{StaticResource Placer}" ConverterParameter="0.5">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource AncestorType={x:Type Canvas}}"/>
<Binding Path="Width" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
In order to parameterize MultiBinding.ConverterParameter you may simply use a binding.
EDIT: I stand corrected about binding to MultiBinding.ConverterParameter: it is not possible since it is not a DependencyProperty but you can work around it.

Categories

Resources