Skip to content

Commit 3c4ab94

Browse files
committed
customizable version of the RatingBar
1 parent 068107c commit 3c4ab94

File tree

8 files changed

+253
-325
lines changed

8 files changed

+253
-325
lines changed

MainDemo.Wpf/Buttons.xaml

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,33 @@
154154
</StackPanel>
155155
<TextBlock Margin="0 24 0 0" Grid.Row="9">Rating bar</TextBlock>
156156
<StackPanel Grid.Row="10" Margin="0 16 0 0" Orientation="Horizontal">
157-
<wpf:RatingBar x:Name="ratingBar" Rating="3" PathData="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z" />
158-
<TextBlock Text="Rating: " VerticalAlignment="Center" />
157+
<wpf:RatingBar x:Name="ratingBar" MaxRating="5" Rating="2">
158+
<wpf:RatingBar.ButtonContentTemplate>
159+
<DataTemplate>
160+
<Viewbox Width="21" Height="21">
161+
<Canvas Width="24" Height="24">
162+
<Path Data="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
163+
Fill="{StaticResource PrimaryHueMidBrush}" />
164+
</Canvas>
165+
</Viewbox>
166+
</DataTemplate>
167+
</wpf:RatingBar.ButtonContentTemplate>
168+
</wpf:RatingBar>
169+
<TextBlock Text="Rating: " VerticalAlignment="Center" Margin="10,0,0,0" />
159170
<TextBlock x:Name="ratingTextBlock" Text="{Binding Path=Rating, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" />
160-
<wpf:RatingBar Rating="3" IsEnabled="False" Margin="40,0,0,0" PathData="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z" />
171+
<wpf:RatingBar MaxRating="7" Rating="5" IsEnabled="False" Margin="20,0,0,0" Width="224">
172+
<wpf:RatingBar.ButtonContentTemplate>
173+
<DataTemplate>
174+
<Viewbox Width="21" Height="21">
175+
<Canvas Width="24" Height="24">
176+
<Path Data="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"
177+
Fill="{StaticResource PrimaryHueMidBrush}" />
178+
</Canvas>
179+
</Viewbox>
180+
</DataTemplate>
181+
</wpf:RatingBar.ButtonContentTemplate>
182+
</wpf:RatingBar>
183+
<TextBlock Text="disabled" VerticalAlignment="Center" Margin="10,0,0,0" />
161184
</StackPanel>
162185
</Grid>
163186
</UserControl>

MaterialDesignThemes.Wpf/MaterialDesignThemes.Wpf.csproj

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@
6464
<SubType>Designer</SubType>
6565
<Generator>MSBuild:Compile</Generator>
6666
</Page>
67-
<Page Include="RatingBar.xaml">
68-
<SubType>Designer</SubType>
69-
<Generator>MSBuild:Compile</Generator>
70-
</Page>
7167
<Page Include="Themes\Generic.xaml">
7268
<Generator>MSBuild:Compile</Generator>
7369
<SubType>Designer</SubType>
@@ -124,6 +120,10 @@
124120
<SubType>Designer</SubType>
125121
<Generator>MSBuild:Compile</Generator>
126122
</Page>
123+
<Page Include="Themes\MaterialDesignTheme.RatingBar.xaml">
124+
<SubType>Designer</SubType>
125+
<Generator>MSBuild:Compile</Generator>
126+
</Page>
127127
<Page Include="Themes\MaterialDesignTheme.ScrollBar.xaml">
128128
<SubType>Designer</SubType>
129129
<Generator>MSBuild:Compile</Generator>
@@ -248,9 +248,7 @@
248248
<DependentUpon>Settings.settings</DependentUpon>
249249
<DesignTimeSharedInput>True</DesignTimeSharedInput>
250250
</Compile>
251-
<Compile Include="RatingBar.xaml.cs">
252-
<DependentUpon>RatingBar.xaml</DependentUpon>
253-
</Compile>
251+
<Compile Include="RatingBar.cs" />
254252
<Compile Include="TextFieldAssist.cs" />
255253
<Compile Include="Converters\TextFieldHintVisibilityConverter.cs" />
256254
<Compile Include="TimePicker.cs" />

MaterialDesignThemes.Wpf/RatingBar.cs

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Windows;
7+
using System.Windows.Controls;
8+
using System.Windows.Data;
9+
10+
namespace MaterialDesignThemes.Wpf
11+
{
12+
/// <summary>
13+
/// A custom control implementing a rating bar.
14+
/// The icon aka content may be set as a DataTemplate via the ButtonContentTemplate property.
15+
/// </summary>
16+
public class RatingBar : Control
17+
{
18+
private const string RatingBarGridPartName = "PART_ratingBarGrid";
19+
20+
private static readonly DependencyProperty ButtonContentTemplateProperty = DependencyProperty.Register("ButtonContentTemplate", typeof(DataTemplate), typeof(RatingBar));
21+
22+
public DataTemplate ButtonContentTemplate
23+
{
24+
get { return (DataTemplate)GetValue(ButtonContentTemplateProperty); }
25+
26+
set {
27+
SetValue(ButtonContentTemplateProperty, value);
28+
29+
RebuildUi();
30+
}
31+
}
32+
33+
public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxRating", typeof(int), typeof(RatingBar));
34+
35+
public int MaxRating
36+
{
37+
get { return (int)GetValue(MaxValueProperty); }
38+
39+
set
40+
{
41+
if (value < 1)
42+
{
43+
throw new ArgumentException("the maximum value must be greater than 1");
44+
}
45+
46+
SetValue(MaxValueProperty, value);
47+
48+
RebuildUi();
49+
}
50+
}
51+
52+
public static readonly DependencyProperty RatingProperty = DependencyProperty.Register("Rating", typeof(int), typeof(RatingBar));
53+
54+
public int Rating
55+
{
56+
get { return (int)GetValue(RatingProperty); }
57+
58+
set
59+
{
60+
int rating = value;
61+
62+
if (rating < 1)
63+
{
64+
rating = 1;
65+
}
66+
67+
if (rating > MaxRating)
68+
{
69+
rating = MaxRating;
70+
}
71+
72+
SetValue(RatingProperty, rating);
73+
74+
UpdateButtonOpacity();
75+
}
76+
}
77+
78+
private Button[] _ratingButtons;
79+
80+
static RatingBar()
81+
{
82+
DefaultStyleKeyProperty.OverrideMetadata(typeof(RatingBar), new FrameworkPropertyMetadata(typeof(RatingBar)));
83+
}
84+
85+
public RatingBar()
86+
{
87+
MaxRating = 5;
88+
Rating = 3;
89+
}
90+
91+
public override void OnApplyTemplate()
92+
{
93+
RebuildUi();
94+
95+
base.OnApplyTemplate();
96+
}
97+
98+
private void RebuildUi()
99+
{
100+
// rebuild the grid as basic layout
101+
Grid grid = GetTemplateChild(RatingBarGridPartName) as Grid;
102+
103+
if (grid != null)
104+
{
105+
grid.ColumnDefinitions.Clear();
106+
grid.Children.Clear();
107+
108+
for (int i = 0; i < MaxRating; i++)
109+
{
110+
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1.0, GridUnitType.Star) });
111+
}
112+
113+
// create buttons
114+
if (_ratingButtons != null)
115+
{
116+
foreach (Button button in _ratingButtons)
117+
{
118+
button.Click -= RatingButtonClick;
119+
}
120+
}
121+
122+
_ratingButtons = new Button[MaxRating];
123+
124+
for (int i = 0; i < MaxRating; i++)
125+
{
126+
Button button = new Button();
127+
button.ContentTemplate = ButtonContentTemplate;
128+
129+
button.DataContext = this;
130+
Binding enabledBinding = new Binding("IsEnabled");
131+
enabledBinding.Mode = BindingMode.OneWay;
132+
enabledBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
133+
BindingOperations.SetBinding(button, Button.IsEnabledProperty, enabledBinding);
134+
135+
button.Click += RatingButtonClick;
136+
137+
_ratingButtons[i] = button;
138+
139+
Grid.SetColumn(button, i);
140+
Grid.SetRow(button, 0);
141+
grid.Children.Add(button);
142+
143+
Style style = null;
144+
Style basedOn = TryFindResource("MaterialDesignRatingBarButton") as Style;
145+
146+
if (basedOn != null)
147+
{
148+
style = new Style(typeof(Button), basedOn);
149+
}
150+
else
151+
{
152+
style = new Style(typeof(Button));
153+
}
154+
155+
button.Style = style;
156+
}
157+
158+
UpdateButtonOpacity();
159+
}
160+
}
161+
162+
private void UpdateButtonOpacity()
163+
{
164+
if (_ratingButtons != null)
165+
{
166+
for (int i = 0; i < _ratingButtons.Length; i++)
167+
{
168+
if ((i + 1) <= Rating)
169+
{
170+
_ratingButtons[i].Opacity = 1.0;
171+
}
172+
else
173+
{
174+
_ratingButtons[i].Opacity = 0.5;
175+
}
176+
}
177+
}
178+
}
179+
180+
private int GetRatingForButton(Button ratingButton)
181+
{
182+
for (int i = 0; i < _ratingButtons.Length; i++)
183+
{
184+
if (_ratingButtons[i] == ratingButton)
185+
{
186+
return i + 1;
187+
}
188+
}
189+
190+
return 0;
191+
}
192+
193+
private void RatingButtonClick(object sender, RoutedEventArgs args)
194+
{
195+
Rating = GetRatingForButton(sender as Button);
196+
}
197+
}
198+
}

0 commit comments

Comments
 (0)