2009-10-22 96 views
1

这应该是一个非常简单的例子,但我拉着头发试图让它工作。这里是设置:WPF用户控件绑定问题

我正在设计一个应用程序,将有一些只读模式和编辑模式的数据。所以我创建了一个用户控件,这是一个文本框和文本块绑定到相同的文本数据,并基于EditableMode属性有条件地可见(所以当它是可编辑的文本框显示,当它不是文本块显示)

现在,我想在我的主窗口中拥有许多这些控件,并让它们都绑定一个单一的布尔属性。当通过按钮更改该属性时,我希望所有TextBlocks都变成TextBoxes或返回。

我的问题是,控制设置正确的绑定,如果我做myUserControl.Editable = true。但是,如果将其绑定到bool属性,它不会改变。

这里是我的用户控件的代码:

<UserControl x:Class="CustomerCareTool.Controls.EditableLabelControl" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:src="clr-namespace:CustomerCareTool.Converters" 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
<UserControl.Resources> 
    <src:BoolToVisibility x:Key="boolToVisibility" Inverted="False" /> 
    <src:BoolToVisibility x:Key="invertedBoolToVisibility" Inverted="True" /> 
</UserControl.Resources> 
<Grid> 
    <TextBlock Name="textBlock" Text="{Binding Path=TextBoxValue}" Visibility="{Binding Path=EditableMode, Converter={StaticResource invertedBoolToVisibility}}"/> 
    <TextBox Name="textBox" Visibility="{Binding Path=EditableMode, Converter={StaticResource boolToVisibility}}"> 
     <TextBox.Text> 
      <Binding Path="TextBoxValue" UpdateSourceTrigger="PropertyChanged"/> 
     </TextBox.Text> 
    </TextBox> 
</Grid> 

我用了一个转换器转换成布尔能见度和逆布尔能见度。不知道这是否完全需要。

这是后面的代码:

public partial class EditableLabelControl : UserControl 
{ 
    public EditableLabelControl() 
    { 
     InitializeComponent(); 
    } 

    public string TextBoxValue 
    { 
     get { return (string)GetValue(TextBoxValueProperty); } 
     set { SetValue(TextBoxValueProperty, value); } 
    } 

    public static readonly DependencyProperty TextBoxValueProperty = 
     DependencyProperty.Register("TextBoxValue", typeof(string), typeof(EditableLabelControl), new UIPropertyMetadata()); 


    public bool EditableMode 
    { 
     get { return (bool)GetValue(EditableModeProperty); } 
     set { SetValue(EditableModeProperty, value); } 
    } 

    public static readonly DependencyProperty EditableModeProperty = 
     DependencyProperty.Register("EditableMode", typeof(bool),typeof(EditableLabelControl), new UIPropertyMetadata(false, EditableModePropertyCallBack)); 

static void EditableModePropertyCallBack(DependencyObject property, 
DependencyPropertyChangedEventArgs args) 
    { 
     var editableLabelControl = (EditableLabelControl)property; 
     var editMode = (bool)args.NewValue; 

     if (editMode) 
     { 
      editableLabelControl.textBox.Visibility = Visibility.Visible; 
      editableLabelControl.textBlock.Visibility = Visibility.Collapsed; 
     } 
     else 
     { 
      editableLabelControl.textBox.Visibility = Visibility.Collapsed; 
      editableLabelControl.textBlock.Visibility = Visibility.Visible; 
     } 
    } 
} 

现在我的主要应用程序,我已经添加这样的控制:

<Controls:EditableLabelControl x:Name="testCtrl" EditableMode="{Binding Path=Editable}" TextBoxValue="John Smith" Grid.Row="0"/> 

对于同一应用程序的DataContext设置自

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

而后面的代码看起来像这样:

public partial class OrderInfoView : Window, INotifyPropertyChanged 

{ 
    public OrderInfoView() 
    { 
     InitializeComponent(); 
    } 

    private void Button_Click_1(object sender, RoutedEventArgs e) 
    { 
     Editable = !Editable; 
    } 

    private bool _editable = false; 
    public bool Editable 
    { 
     get 
     { 
      return _editable; 
     } 
     set 
     { 
      _editable = value; 
      OnPropertyChanged("Editable"); 
     } 
    } 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged == null) return; 

     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 


    public event PropertyChangedEventHandler PropertyChanged; 
} 

点击该按钮并没有做任何事情:(我试过一切都得到这个工作,并没有骰子。真的很感谢一些帮助!


我尝试了以下内容,仍然不能正常工作:

public bool Editable 
    { 
     get { return (bool)GetValue(EditableProperty); } 
     set { SetValue(EditableProperty, value); } 
    } 

    public static readonly DependencyProperty EditableProperty = 
     DependencyProperty.Register("Editable", typeof(bool), typeof(OrderInfoView), new UIPropertyMetadata(false)); 
+0

我建议把问题解决。你确定你的可编辑绑定正在工作吗?为了测试这个,你可以将你的{Binding Path = Editable}绑定复制到一个普通的TextBlock中,并查看点击按钮时的true和false开关。 如果该绑定起作用,然后在EditableModePropertyCallBack方法中抛出一个断点并确保获得命中。如果中断点被击中,然后逐步完成并确保它按预期执行。 让我知道你会得到什么结果。 –

+0

我会给它一个镜头并发布更新。非常感谢您的帮助! –

回答

2

它看起来像你的解决方案可能会比需要的更复杂。如果所有你想要做的都是禁用TextBox看起来像一个TextBlock,那么你可以使用触发器和模板来做到这一点。然后,您可以将该样式应用于所有文本框。

下面是这一做法的一个例子:

<Window x:Class="WpfApplication25.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" 
     Height="300" 
     Width="300" 
     > 

    <Window.Resources> 

     <!-- Disable TextBox Style --> 
     <Style x:Key="_DisableTextBoxStyle" TargetType="TextBox"> 
      <Style.Triggers> 
       <Trigger Property="IsEnabled" Value="False"> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="TextBox"> 
           <!-- 
           Be sure to apply all necessary TemplateBindings between 
           the TextBox and TextBlock template. 
           --> 
           <TextBlock Text="{TemplateBinding Text}" 
              FontFamily="{TemplateBinding FontFamily}" 
              /> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 

    </Window.Resources> 

    <StackPanel> 
     <TextBox IsEnabled="{Binding IsChecked, ElementName=uiIsEnabled}" 
       Style="{StaticResource _DisableTextBoxStyle}" 
       /> 

     <ToggleButton x:Name="uiIsEnabled" Content="Enable" IsChecked="True" /> 
    </StackPanel> 
</Window> 
+0

真的很酷,谢谢。问题是,这个解决方案是否允许我这样做:将文本框边界改为红色,当点击按钮切换时,下次显示文本框时它会将边框恢复为原始值? 另外,任何想法,为什么我以前的解决方案不工作? 非常感谢!!! –

+0

我不完全确定你在问什么,但有很多事情你可以用Trigger和DataTrigger做。 ,您可以使用触发器中的setter来更改边框笔刷,以检查Text是{x:Null}还是Text.Length是0。 –

+0

很酷,非常感谢,我会检查出来的! –

0

INotifyPropertyChanged的不为自DependencyObject派生类的工作。

OrderInfoView中的可编辑属性必须是依赖项属性,以便绑定正常工作,虽然技术上你的代码是正确的,但我觉得它在WPF中的错误是当对象是依赖对象时它忽略INotifyPropertyChanged事件,因为它正在搜索通知财产制度。

<Controls:EditableLabelControl x:Name="testCtrl" 
EditableMode="{Binding Path=Editable,ElementName=userControl}" TextBoxValue="John Smith" Grid.Row="0"/> 

在绑定标记指定的ElementName并与第十名的用户控件:字段名或x:名称

+0

这也没有效果。可编辑也是主窗口的属性,而不是用户控件。然后主窗口将数据上下文设置为self:DataContext =“{Binding RelativeSource = {RelativeSource Self}} –

+0

然后将elementname设置为主窗口,给它一些名称并尝试。 –

0

我只是碰到这种搜索出来的东西。

没有阅读详细您的文章(没有时间大气压抱歉)在我看来,你有一个类似的问题给一个我张贴了关于在这里:​​ http://jonsblogat.blogspot.com/2009/11/wpf-windowdatacontext-and.html

总之,移动你的你的主绑定窗口添加到Grid并使用相对绑定来查看是否可以修复您的问题。