【发布时间】:2015-07-08 19:10:45
【问题描述】:
我正在 WPF 中创建一个包含文本框、图像按钮和组合框的自定义控件。我能够正确布局所有内容,并且所有绑定都适用于除组合框的 SelectedItem 之外的所有内容。
这里是自定义控件代码:
public class GelPakPickerOverlay : Border
{
public static readonly DependencyProperty SelectedGelPakProperty =
DependencyProperty.Register(
"SelectedGelPak",
typeof(object),
typeof(GelPakPickerOverlay),
new FrameworkPropertyMetadata(
null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public static readonly DependencyProperty LocationProperty =
DependencyProperty.Register(
"Location",
typeof(string),
typeof(GelPakPickerOverlay),
new FrameworkPropertyMetadata(string.Empty, OnLocationChanged));
public static readonly DependencyProperty GelPakSourceProperty =
DependencyProperty.Register(
"GelPakSource",
typeof(IEnumerable),
typeof(GelPakPickerOverlay),
new FrameworkPropertyMetadata(null, OnGelPakSourceChanged));
public static readonly DependencyProperty SaveCommandProperty =
DependencyProperty.Register(
"SaveCommand",
typeof(ICommand),
typeof(GelPakPickerOverlay),
new FrameworkPropertyMetadata(null, OnSaveCommandChanged));
private static ComboBox gpSelector;
private static TextBox gpLocation;
private static Button saveButton;
public GelPakPickerOverlay()
{
Height = 98;
gpSelector = new ComboBox();
gpSelector.Width = 100;
gpSelector.Margin = new Thickness(10);
gpSelector.HorizontalAlignment = HorizontalAlignment.Left;
gpSelector.VerticalAlignment = VerticalAlignment.Center;
Grid grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition());
ColumnDefinition def = new ColumnDefinition();
def.Width = new GridLength(40);
grid.ColumnDefinitions.Add(def);
gpLocation = new TextBox();
gpLocation.Style = (Style) FindResource("TextBoxStyleBase");
gpLocation.Width = 70;
gpLocation.Margin = new Thickness(10);
gpLocation.HorizontalAlignment = HorizontalAlignment.Left;
gpLocation.VerticalAlignment = VerticalAlignment.Center;
Grid.SetColumn(gpLocation, 0);
saveButton = new Button();
saveButton.Style = (Style) FindResource("SaveButton");
saveButton.Margin = new Thickness(0, 10, 10, 10);
saveButton.HorizontalAlignment = HorizontalAlignment.Center;
Grid.SetColumn(saveButton, 1);
grid.Children.Add(gpLocation);
grid.Children.Add(saveButton);
StackPanel mainChild = new StackPanel();
mainChild.Orientation = Orientation.Vertical;
mainChild.Children.Add(gpSelector);
mainChild.Children.Add(grid);
Child = mainChild;
}
public object SelectedGelPak
{
get { return GetValue(SelectedGelPakProperty); }
set { SetValue(SelectedGelPakProperty, value); }
}
public string Location
{
get { return GetValue(LocationProperty).ToString(); }
set { SetValue(LocationProperty, value); }
}
public IEnumerable GelPakSource
{
get { return (IEnumerable) GetValue(GelPakSourceProperty); }
set { SetValue(GelPakSourceProperty, value); }
}
public ICommand SaveCommand
{
get { return (ICommand) GetValue(SaveCommandProperty); }
set { SetValue(SaveCommandProperty, value); }
}
private static void OnLocationChanged(
DependencyObject source, DependencyPropertyChangedEventArgs e)
{
if (gpLocation != null)
{
gpLocation.Text = e.NewValue.ToString();
}
}
private static void OnGelPakSourceChanged(
DependencyObject source, DependencyPropertyChangedEventArgs e)
{
if (gpSelector != null)
{
gpSelector.ItemsSource = (IEnumerable) e.NewValue;
}
}
private static void OnSaveCommandChanged(
DependencyObject source, DependencyPropertyChangedEventArgs e)
{
if (saveButton != null)
{
saveButton.Command = (ICommand) e.NewValue;
}
}
}
这是它在主窗口中的引用方式:
<ctl:GelPakPickerOverlay
Width="132"
DockPanel.Dock="Right"
VerticalAlignment="Bottom"
Background="{StaticResource primaryBrush}"
BorderBrush="{StaticResource accentBrushOne}"
BorderThickness="2,2,0,0"
Visibility="{
Binding GelPakPickerViewModel.IsPickerVisible,
Converter={StaticResource BoolToHiddenVisConverter},
FallbackValue=Visible}"
GelPakSource="{Binding GelPakPickerViewModel.GelPakList}"
SelectedGelPak="{Binding GelPakPickerViewModel.SelectedGelPak}"
Location="{Binding GelPakPickerViewModel.GelPakLocation, UpdateSourceTrigger=LostFocus}"
SaveCommand="{Binding GelPakPickerViewModel.UpdateGpDataCommand}"/>
此窗口的数据上下文是 MainWindowViewModel,它有一个 GelPakPickerViewModel 属性,所有绑定都连接到该属性。 “Location”、“GelPakSource”和“SaveCommand”属性都正常工作,并按照我期望的方式将所有内容路由到 GelPakPickerViewModel。但是,当您从组合框中选择任何内容时,它实际上永远不会进入 GelPakViewModels SelectedGelPak 属性(属于 GelPak 类型)。
这里发生了什么?有没有人有任何建议来解决这个问题?!?
编辑:我向 SelectedGelPakProperty 添加了一个属性更改事件侦听器,如下所示:
public static readonly DependencyProperty SelectedGelPakProperty =
DependencyProperty.Register(
"SelectedGelPak",
typeof(object),
typeof(GelPakPickerOverlay),
new FrameworkPropertyMetadata(null, OnSelectedGelPakChanged));
........
private static void OnSelectedGelPakChanged(
DependencyObject source, DependencyPropertyChangedEventArgs e)
{
if (gpLocation != null)
{
gpSelector.SelectedItem = e.NewValue;
}
}
但这仍然不会真正改变视图模型中的 SelectedGelPak 对象。
【问题讨论】:
标签: c# wpf data-binding custom-controls dependency-properties