我在用户控件中遇到按钮绑定问题。这件事让我困扰了好几天,我似乎无法让它正常工作。
这个想法是在用户控制中有几个按钮(可以动态添加)。每个按钮可以具有不同的标题和不同的值。按钮应该能够禁用/启用彼此,例如"选项1"点击"选项9"应该被禁用。 User Control Example
用户控件是一个简单的StackPanel,带有多个按钮,如图所示。 我已将DependencyProperty实现为名为Value的int。单击任何按钮时,Value将更改按钮的值。我已将该值与价值模型联系起来。单击任何按钮时,模型值会发生变化。但是,当我更改模型值时,控制值不会改变。 如何正确地双向进行?如何只选择模型中的一个按钮?我也尝试将INotifyPropertyChanged实现到我的用户控件中,但它没有用。我也尝试了其他一些我在这里读过的东西,但它没有用。
简而言之,我需要一组具有不同值的按钮,并在单击时将自己的值映射到一个值。我应该可以从我的模型中获取/设置该值。
我还需要某种方法来启用/禁用按钮,具体取决于单击哪个按钮。正如我已经写过的,如果按钮"选项1"单击它应禁用"选项9"按钮。有什么办法通过数据绑定吗?价值转换器?
日Thnx!
namespace TestApp
{
public partial class SingleOptionControl : UserControl
{
private static SolidColorBrush _selectedColorBrush = new SolidColorBrush(Color.FromRgb(0, 120, 200));
private SingleOptionModel _model;
private List<Button> _buttons;
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(SingleOptionControl), new PropertyMetadata(null));
public SingleOptionControl()
{
InitializeComponent();
_buttons = new List<Button>();
this.DataContext = this;
}
private void buttonIndex_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
ButtonOption option = (ButtonOption)button.Tag;
int index = option.Index;
Console.WriteLine("Current index = {0} | Value = {1}", index, option.Value);
// Update the Value
Value = option.Value;
// Deselect
DeselectButtons();
// Select
SelectButton(index);
}
private void SelectButton(int index)
{
Button button = _buttons[index];
button.Foreground = _selectedColorBrush;
button.FontWeight = FontWeights.Bold;
button.FontSize = 14.0;
}
private void DeselectButtons()
{
foreach (Button button in _buttons)
{
button.Foreground = Brushes.Black;
button.FontWeight = FontWeights.Normal;
button.FontSize = 12.0;
}
}
public void Create(SingleOptionModel model)
{
_model = model;
labelTitle.Content = model.Title;
int index = 0;
List<ButtonSection> sections = model.Sections;
foreach (ButtonSection section in sections)
{
List<ButtonOption> options = section.Options;
foreach (ButtonOption option in options)
{
option.Index = index;
Button button = createButton(option);
button.Click += buttonIndex_Click;
stackPanel1.Children.Add(button);
_buttons.Add(button);
index++;
}
Separator separator = createSeparator();
stackPanel1.Children.Add(separator);
}
labelDefaultValue.Content = model.DefaultOption.Value;
Value = model.DefaultOption.Value;
}
private Button createButton(ButtonOption option)
{
Button button = new Button();
button.FontSize = 12.0;
button.Content = option.Title;
button.Tag = option;
button.Height = 36;
button.MinWidth = 48;
button.Padding = new Thickness(6, 0, 6, 0);
button.Margin = new Thickness(1, 0, 1, 0);
return button;
}
private Separator createSeparator()
{
Separator separator = new Separator();
separator.Width = 6;
separator.Background = null;
return separator;
}
}
}
<UserControl x:Class="TestApp.SingleOptionControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="167" d:DesignWidth="800">
<Grid Name="gridMain" Height="96">
<Label Height="30" HorizontalAlignment="Stretch" Name="labelTitle" VerticalAlignment="Top" Background="{x:Null}" VerticalContentAlignment="Center" FontSize="18" FontStyle="Normal" FontWeight="Bold" Padding="10,0,0,0" Margin="0,2,0,0" />
<StackPanel Height="40" HorizontalAlignment="Stretch" Margin="10,32,0,0" Name="stackPanel1" VerticalAlignment="Top" Orientation="Horizontal"></StackPanel>
<Label Content="Default:" Height="28" HorizontalAlignment="Left" Margin="4,68,0,0" Name="label2" VerticalAlignment="Top" Width="50" Padding="10,0,0,0" VerticalContentAlignment="Center" />
<Label Content="Value" Height="28" HorizontalAlignment="Left" Margin="60,68,0,0" Name="labelDefaultValue" VerticalAlignment="Top" Width="384" Padding="0" VerticalContentAlignment="Center" />
<Rectangle Height="1" HorizontalAlignment="Stretch" Name="rectangle1" Stroke="{x:Null}" VerticalAlignment="Top" Fill="#14000000" />
</Grid>
</UserControl>
namespace TestApp
{
public class TestModel : INotifyPropertyChanged
{
private byte _testValue;
public byte TestValue
{
get { return _testValue; }
set
{
_testValue = value;
OnPropertyChanged("TestValue");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}