WPF自定义ComboBox初始值设置

时间:2013-02-01 10:12:20

标签: wpf combobox custom-controls

我已经构建了一个自定义ComboBox,它在设置ReadOnly时显示为TextBox:

<local:BoolToVisibilityConverter FalseValue="Hidden" TrueValue="Visible" x:Key="BoolVis" />
<local:BoolToVisibilityConverter FalseValue="Visible" TrueValue="Hidden" x:Key="BoolVisRev" />

<Style TargetType="{x:Type local:ComboBoxG}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ComboBoxG}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <Grid>
                        <ComboBox ItemsSource="{TemplateBinding ItemsSource}"
                                  DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
                                  SelectedValuePath="{TemplateBinding SelectedValuePath}"
                                  SelectedIndex="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedIndex, Mode=TwoWay}"
                                  Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsReadOnly, Converter={StaticResource BoolVisRev}}"
                                  IsDropDownOpen="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsDropDownOpen, Mode=TwoWay}"
                                  IsTabStop="False">
                        </ComboBox>
                        <TextBox Text="{TemplateBinding Text}" 
                                 Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsReadOnly, Converter={StaticResource BoolVis}}"
                                 IsTabStop="False">
                        </TextBox>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

它工作得很好,除了我实例化并一次性设置一个值。这不起作用......

private void One_OnClick(object sender, RoutedEventArgs e)
{
    cmb = new ComboBoxG();
    Stack.Children.Add(cmb);

    var dict = new Dictionary<int, string> { { 0, "aaa" }, { 1, "bbb" }, { 2, "ccc" }, { 3, "ddd" }, };
    cmb.ItemsSource = dict;
    cmb.DisplayMemberPath = "Value";
    cmb.SelectedValuePath = "Key";
    cmb.SelectedValue = 3;
}

......而这确实......

private void One_OnClick(object sender, RoutedEventArgs e)
{
    cmb = new ComboBoxG();
    Stack.Children.Add(cmb);

    var dict = new Dictionary<int, string> { { 0, "aaa" }, { 1, "bbb" }, { 2, "ccc" }, { 3, "ddd" }, };
    cmb.ItemsSource = dict;
    cmb.DisplayMemberPath = "Value";
    cmb.SelectedValuePath = "Key";
    cmb.Loaded += cmb_Loaded;
}

private void cmb_Loaded(object sender, RoutedEventArgs e)
{
    cmb.SelectedValue = 3;
}

所以我可以解决它,但它使这个控件的一些用途变得尴尬。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

我之前也遇到过这个问题,到目前为止,唯一的半愉快解决方法是在一个方法中完成这一切 是让消息队列通过Loaded阶段排出。请注意,我并不为此感到骄傲,但WPF分阶段做事,有时你更喜欢把所有东西放在一起。您可以将cmd.SelectedValue = 3放入我认为的委托中,但这是一个品味问题......

        cmb = new ComboboxG();
        theStack.Children.Add(cmb);

        var dict = new Dictionary<int, string> { { 0, "aaa" }, { 1, "bbb" }, { 2, "ccc" }, { 3, "ddd" }, };
        cmb.ItemsSource = dict;
        cmb.DisplayMemberPath = "Value";
        cmb.SelectedValuePath = "Key";

        Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Loaded);

        cmb.SelectedValue = 3;

请注意这将允许事件运行,所以要小心重入!

答案 1 :(得分:0)

您是否尝试过设置所选索引?

private void One_OnClick(object sender, RoutedEventArgs e)
{
    cmb = new ComboBoxG();
    Stack.Children.Add(cmb);

    var dict = new Dictionary<int, string> { { 0, "aaa" }, { 1, "bbb" }, { 2, "ccc" }, { 3, "ddd" }, };
    cmb.ItemsSource = dict;
    cmb.DisplayMemberPath = "Value";
    cmb.SelectedValuePath = "Key";
    cmb.SelectedIndex = 3;
}

答案 2 :(得分:0)

尝试设置SelectedItem而不是Index